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

View file

@ -127,11 +127,9 @@ enum Commands {
/// Generate details.csv with all timing data
Details,
/// Show best car for a specific track/condition/RQ combination
Track {
track: String,
condition: String,
rq: u8,
},
Track { track: String, condition: String, rq: u8 },
/// Generate improve.csv (owned cars not in final config, sorted by best tracks)
Improve,
}
// ---------------------------------------------------------------------------
@ -170,29 +168,70 @@ async fn run() -> Result<(), AppError> {
commands::fetch::run_fetch(&cli.cars_db, &cli.tracks_db, &cli.times_dir).await?;
}
Commands::Best { min_count } => {
commands::best::run_best(&cli.my_cars, &cli.cars_db, &cli.times_dir, &cli.output_dir, min_count).await?;
commands::best::run_best(
&cli.my_cars,
&cli.cars_db,
&cli.times_dir,
&cli.output_dir,
min_count,
)
.await?;
}
Commands::Trash => {
commands::trash::run_trash(&cli.my_cars, &cli.cars_db, &cli.times_dir, &cli.output_dir).await?;
commands::trash::run_trash(&cli.my_cars, &cli.cars_db, &cli.times_dir, &cli.output_dir)
.await?;
}
Commands::Wishlist { min_count, max_wishlist } => {
commands::wishlist::run_wishlist(
&cli.my_cars, &cli.cars_db, &cli.times_dir, &cli.output_dir, min_count, max_wishlist,
).await?;
&cli.my_cars,
&cli.cars_db,
&cli.times_dir,
&cli.output_dir,
min_count,
max_wishlist,
)
.await?;
}
Commands::All { min_count, max_wishlist } => {
commands::all::run_all(
&cli.my_cars, &cli.cars_db, &cli.times_dir, &cli.output_dir, min_count, max_wishlist,
).await?;
&cli.my_cars,
&cli.cars_db,
&cli.times_dir,
&cli.output_dir,
min_count,
max_wishlist,
)
.await?;
}
Commands::Details => {
commands::details::run_details(&cli.my_cars, &cli.cars_db, &cli.times_dir, &cli.output_dir).await?;
commands::details::run_details(
&cli.my_cars,
&cli.cars_db,
&cli.times_dir,
&cli.output_dir,
)
.await?;
}
Commands::Track { track, condition, rq } => {
commands::track::run_track(
&cli.my_cars, &cli.cars_db, &cli.times_dir, &cli.output_dir,
&track, &condition, rq,
).await?;
&cli.my_cars,
&cli.cars_db,
&cli.times_dir,
&cli.output_dir,
&track,
&condition,
rq,
)
.await?;
}
Commands::Improve => {
commands::improve::run_improve(
&cli.my_cars,
&cli.cars_db,
&cli.times_dir,
&cli.output_dir,
)
.await?;
}
}
Ok(())