fix(fifa17): key the kit home/away split on the carddbid, not assetid
Staging served `kits=2 kitsHome=0 kitsAway=0`: the split compared the catalog `asset_id` against `fcc_kitcards.assetid` (14/15), but a kit's catalog `asset_id` IS its carddbid (6300006), not that column, so neither family ever matched. The carddbid range is the same fact in the form we actually carry: across all 1482 kit rows, assetid 14 covers precisely the 828 `63xxxxx` ids and assetid 15 precisely the 654 `64xxxxx` ids, with no exceptions either way. Keying on the id we already have avoids carrying `assetid` as a second source of truth for the same split. Tests now use the real team-21 pair (6300006 home / 6400003 away). Verified against the staging stack: `kits=2 kitsHome=1 kitsAway=1`, team-21 bucket 2, `?type=kit` still activeHomeKit/activeAwayKit, `?type=player` 12.
This commit is contained in:
@@ -66,12 +66,20 @@ const S_KITS_HOME: i64 = 0x29;
|
|||||||
const S_KITS_AWAY: i64 = 0x2A;
|
const S_KITS_AWAY: i64 = 0x2A;
|
||||||
const S_BADGES: i64 = 0x2D;
|
const S_BADGES: i64 = 0x2D;
|
||||||
|
|
||||||
/// `fcc_kitcards.assetid` splits the kit table into the home and away families.
|
/// First `carddbid` of the AWAY kit family. `fcc_kitcards` is split into a
|
||||||
/// Verified across all 1482 rows of the FIFA 17 kit table: assetid 14 covers
|
/// `63xxxxx` home family and a `64xxxxx` away family, and the table's own
|
||||||
/// exactly the `63xxxxx` carddbids (828 rows) and assetid 15 exactly the
|
/// `assetid` column agrees exactly: across all 1482 rows, assetid 14 covers
|
||||||
/// `64xxxxx` ones (654 rows), with no exceptions in either direction.
|
/// precisely the 828 `63xxxxx` ids and assetid 15 precisely the 654 `64xxxxx`
|
||||||
const KIT_ASSET_HOME: i64 = 14;
|
/// ids, with no exceptions either way. A kit's catalog `asset_id` IS its
|
||||||
const KIT_ASSET_AWAY: i64 = 15;
|
/// carddbid, so the id itself is the family key -- the `assetid` column is not
|
||||||
|
/// carried on the wire and would be a second source of truth for the same fact.
|
||||||
|
const KIT_AWAY_FLOOR: i64 = 6_400_000;
|
||||||
|
|
||||||
|
/// Which kit family an owned kit belongs to. Only meaningful for
|
||||||
|
/// [`ContentKind::Kit`]; the caller filters first.
|
||||||
|
fn is_home_kit(kit: &ClubStatInput) -> bool {
|
||||||
|
kit.asset_id < KIT_AWAY_FLOOR
|
||||||
|
}
|
||||||
|
|
||||||
/// cardsubtypeid (staff family) -> stat id (STAFF_SUBTYPE_STAT).
|
/// cardsubtypeid (staff family) -> stat id (STAFF_SUBTYPE_STAT).
|
||||||
fn staff_stat(subtype: i64) -> Option<i64> {
|
fn staff_stat(subtype: i64) -> Option<i64> {
|
||||||
@@ -240,11 +248,10 @@ pub fn club_stats_body(items: &[ClubStatInput], ctx: ContextField) -> Value {
|
|||||||
.iter()
|
.iter()
|
||||||
.filter(|item| matches!(item.kind, ContentKind::Kit))
|
.filter(|item| matches!(item.kind, ContentKind::Kit))
|
||||||
.collect();
|
.collect();
|
||||||
let kits_with_asset =
|
let home = kits.iter().filter(|kit| is_home_kit(kit)).count() as i64;
|
||||||
|asset: i64| kits.iter().filter(|item| item.asset_id == asset).count() as i64;
|
|
||||||
g.insert(S_KITS, kits.len() as i64);
|
g.insert(S_KITS, kits.len() as i64);
|
||||||
g.insert(S_KITS_HOME, kits_with_asset(KIT_ASSET_HOME));
|
g.insert(S_KITS_HOME, home);
|
||||||
g.insert(S_KITS_AWAY, kits_with_asset(KIT_ASSET_AWAY));
|
g.insert(S_KITS_AWAY, kits.len() as i64 - home);
|
||||||
|
|
||||||
let mut stat: Vec<Value> = g.iter().map(|(sid, v)| row(1, 0, *sid, *v)).collect();
|
let mut stat: Vec<Value> = g.iter().map(|(sid, v)| row(1, 0, *sid, *v)).collect();
|
||||||
|
|
||||||
@@ -344,22 +351,27 @@ mod tests {
|
|||||||
team_id: None,
|
team_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// A kit of the given family (`KIT_ASSET_HOME` / `KIT_ASSET_AWAY`) worn by
|
/// A kit worn by `team`. `carddbid` is the real `fcc_kitcards` id, which is
|
||||||
/// `team`.
|
/// also the catalog `asset_id` and therefore the home/away family key.
|
||||||
fn kit_of(asset_id: i64, team: i64) -> ClubStatInput {
|
fn kit_of(carddbid: i64, team: i64) -> ClubStatInput {
|
||||||
ClubStatInput {
|
ClubStatInput {
|
||||||
kind: ContentKind::Kit,
|
kind: ContentKind::Kit,
|
||||||
subtype: 9,
|
subtype: 9,
|
||||||
rating: 0,
|
rating: 0,
|
||||||
rare: false,
|
rare: false,
|
||||||
asset_id,
|
asset_id: carddbid,
|
||||||
nation_id: None,
|
nation_id: None,
|
||||||
league_id: None,
|
league_id: None,
|
||||||
team_id: Some(team),
|
team_id: Some(team),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Real team-21 kits from `fcc_kitcards`: 6300006 is its home kit and
|
||||||
|
/// 6400003 its away kit.
|
||||||
|
const HOME_KIT: i64 = 6_300_006;
|
||||||
|
const AWAY_KIT: i64 = 6_400_003;
|
||||||
|
|
||||||
fn kit() -> ClubStatInput {
|
fn kit() -> ClubStatInput {
|
||||||
kit_of(KIT_ASSET_HOME, 21)
|
kit_of(HOME_KIT, 21)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn global(body: &Value) -> std::collections::HashMap<String, i64> {
|
fn global(body: &Value) -> std::collections::HashMap<String, i64> {
|
||||||
@@ -432,9 +444,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn kit_counts_split_by_home_and_away_family() {
|
fn kit_counts_split_by_home_and_away_family() {
|
||||||
let items = vec![
|
let items = vec![
|
||||||
kit_of(KIT_ASSET_HOME, 21),
|
kit_of(HOME_KIT, 21),
|
||||||
kit_of(KIT_ASSET_HOME, 38),
|
kit_of(6_300_010, 38),
|
||||||
kit_of(KIT_ASSET_AWAY, 21),
|
kit_of(AWAY_KIT, 21),
|
||||||
];
|
];
|
||||||
let g = global(&club_stats_body(&items, ContextField::Nation));
|
let g = global(&club_stats_body(&items, ContextField::Nation));
|
||||||
assert_eq!(g["kits"], 3);
|
assert_eq!(g["kits"], 3);
|
||||||
@@ -450,9 +462,9 @@ mod tests {
|
|||||||
with_team.team_id = Some(21);
|
with_team.team_id = Some(21);
|
||||||
let items = vec![
|
let items = vec![
|
||||||
with_team,
|
with_team,
|
||||||
kit_of(KIT_ASSET_HOME, 21),
|
kit_of(HOME_KIT, 21),
|
||||||
kit_of(KIT_ASSET_AWAY, 21),
|
kit_of(AWAY_KIT, 21),
|
||||||
kit_of(KIT_ASSET_HOME, 38),
|
kit_of(6_300_010, 38),
|
||||||
];
|
];
|
||||||
let body = club_stats_body(&items, ContextField::Team);
|
let body = club_stats_body(&items, ContextField::Team);
|
||||||
let kits_for = |team: i64| {
|
let kits_for = |team: i64| {
|
||||||
|
|||||||
Reference in New Issue
Block a user