Trends
Best recent hit-rate streaks for players and for teams — two boards that were deliberately not merged, and the three-step chain both run.
| Route | Composed |
|---|---|
/player-trends/[scope] | src/composed/player-trends |
| team scope | src/composed/team-trends |
Best recent hit-rate streaks over a 3-to-40 game window.
A three-step chain, as three derived keys
The board asks three questions in order, and each answer is the next question's input:
- Which events are on that day?
- Which fixtures do those leagues have?
- What are the trends for those fixtures?
That used to be three useEffects with a cancelled flag, seven pieces of
mirror state, and a useRef holding the previous day — and it still had the bug
the flags were there to prevent. setFixtures([]) ran on every day change while
a request for the old day was in flight, so a slow response could repopulate a
board that had moved on.
As keys, the chain is declarative: a step whose input is not ready yet simply has no key, and does not run.
Why the two are not merged
They read different endpoints, return different row shapes and carry
different filters — player trends has four more. The only thing they truly
share is how a day becomes a fixtures window, and that now lives in
lib/trends.ts rather than twice inside two components.
Compare AGS and Assist, which were merged, and for the opposite reason.