diff --git a/CHANGELOG.md b/CHANGELOG.md index 8436a71..fe2157b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ This project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] +### `makegov-tango` + +#### Added + +- **Vehicle company counts** (Tango API 5.8.0): `SHAPE_VEHICLES_MINIMAL` and `SHAPE_VEHICLES_COMPREHENSIVE` now request `holder_count` (distinct companies holding one of the vehicle's IDVs) and `order_winner_count` (distinct companies that have won a task order under it), next to `awardee_count`. + +#### Deprecated + +- **`awardee_count` on vehicles** is deprecated by the Tango API as an alias of `order_winner_count`, and is removed at the API's next major version. The vehicle shapes still request it so existing readers keep working; read `order_winner_count` instead. + ## [0.2.0] — 2026-09-23 Pre-1.0 (SemVer 0.x): the removals under **Breaking** ship without a deprecation cycle. diff --git a/crates/tango/src/shapes.rs b/crates/tango/src/shapes.rs index 8444fc6..4cf73cf 100644 --- a/crates/tango/src/shapes.rs +++ b/crates/tango/src/shapes.rs @@ -110,7 +110,7 @@ pub const SHAPE_IDVS_COMPREHENSIVE: &str = concat!( pub const SHAPE_VEHICLES_MINIMAL: &str = concat!( "uuid,solicitation_identifier,is_synthetic_solicitation,program_acronym,", "organization_id,organization,vehicle_type,description,", - "idv_count,awardee_count,order_count,total_obligated,", + "idv_count,awardee_count,holder_count,order_winner_count,order_count,total_obligated,", "vehicle_obligations,vehicle_contracts_value,latest_award_date,", "solicitation_title,solicitation_date", ); @@ -122,7 +122,7 @@ pub const SHAPE_VEHICLES_COMPREHENSIVE: &str = concat!( "solicitation_title,solicitation_description,solicitation_date,opportunity_id,", "naics_code,psc_code,set_aside,", "fiscal_year,award_date,latest_award_date,last_date_to_order,", - "description,idv_count,awardee_count,order_count,total_obligated,", + "description,idv_count,awardee_count,holder_count,order_winner_count,order_count,total_obligated,", "vehicle_obligations,vehicle_contracts_value,", "type_of_idc,contract_type,metrics(*)", ); @@ -257,3 +257,24 @@ pub const SHAPE_SBIR_SOLICITATIONS_MINIMAL: &str = concat!( "solicitation_id,solicitation_number,title,program,activity,", "cycle_name,solicitation_status,year,start_date,end_date", ); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn vehicle_shapes_carry_company_counts() { + for (name, shape) in [ + ("SHAPE_VEHICLES_MINIMAL", SHAPE_VEHICLES_MINIMAL), + ("SHAPE_VEHICLES_COMPREHENSIVE", SHAPE_VEHICLES_COMPREHENSIVE), + ] { + let fields: Vec<&str> = shape.split(',').collect(); + for want in ["awardee_count", "holder_count", "order_winner_count"] { + assert!( + fields.contains(&want), + "{name} should carry {want:?}: {shape:?}" + ); + } + } + } +}