Fix the team resolve properly: backfill the name BEFORE confirmation

My first attempt did not work in prod -- team stayed 0/323 after deploy.
I resolved the team name AFTER the hint-confirmation check, but the check
itself reads hit.currentTeam.name, which is undefined because
/sports/1/players returns { id, link }. With a FULL-NAME hint (what
snapshotService passes) neither branch of teamRecordMatchesHint could
match: the name branch had no name, and the abbr branch cannot resolve a
full name to an abbr. Confirmation failed, the team was nulled, and my
later backfill ran on an already-null value.

withTeamName() now backfills the name from the cached /teams list BEFORE
any comparison, and is used at all three confirmation sites plus the
return. Verified against the live API on all four cases: no hint, FULL-NAME
hint, abbr hint -> "Philadelphia Phillies"; WRONG hint -> null.

That last case matters most: a wrong hint must still REFUSE. The
confirmation exists so a namesake collision cannot tag a player to a team
he is not on, which would fabricate opponents downstream. Making the match
succeed must not make it succeed wrongly, and a test locks it.

Gates: 4,087 tests / 327 suites green; next build exit 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QJs13VsyiSKYQP6rj3NNmc
This commit is contained in:
Kev
2026-08-01 23:34:16 -04:00
parent cfda597fb5
commit 9fc17a4689
2 changed files with 62 additions and 12 deletions
+34
View File
@@ -66,3 +66,37 @@ describe('the invariants input is the PLAYER team, not the props own game'
expect(players(out)).toEqual(['X']); // abstained — no player team known
});
});
describe('mlbStatsAdapter — the team the invariant depends on', () => {
const { __internals } = require('../../src/services/adapters/mlbStatsAdapter');
const { withTeamName, teamRecordMatchesHint } = __internals || {};
const TEAMS = [{ id: 143, abbr: 'PHI', name: 'Philadelphia Phillies' },
{ id: 141, abbr: 'TOR', name: 'Toronto Blue Jays' }];
it('backfills the team NAME from the id — the list returns { id, link } only', () => {
expect(withTeamName({ id: 143, link: '/api/v1/teams/143' }, TEAMS))
.toEqual({ id: 143, name: 'Philadelphia Phillies' });
});
it('returns null for an absent team rather than an empty shell', () => {
expect(withTeamName(null, TEAMS)).toBeNull();
expect(withTeamName({ link: '/x' }, TEAMS)).toBeNull();
});
it('leaves the name null when the id is unknown — never guessed', () => {
expect(withTeamName({ id: 999 }, TEAMS)).toEqual({ id: 999, name: null });
});
it('a FULL-NAME hint now matches — this is what was silently failing', () => {
// Before the backfill, name was undefined, so a full-name hint could match
// neither branch: confirmation failed and the team was nulled.
const t = withTeamName({ id: 143 }, TEAMS);
expect(teamRecordMatchesHint(t, ['Philadelphia Phillies', 'New York Mets'], TEAMS)).toBe(true);
expect(teamRecordMatchesHint(t, ['PHI'], TEAMS)).toBe(true);
});
it('a WRONG hint still REFUSES — the anti-fabrication guard is preserved', () => {
const t = withTeamName({ id: 143 }, TEAMS);
expect(teamRecordMatchesHint(t, ['Toronto Blue Jays'], TEAMS)).toBe(false);
});
});