One global freshness clock was hiding three different problems
For a while Binderdex had a single pricing-freshness rule: if any card in the whole catalog was older than 30 hours, the global status flipped to breached. That worked when the catalog was small and every card refreshed on the same cadence. It stopped working once the catalog grew into segments that refresh at very different speeds.
A portfolio card (the high-traffic cards people actually browse) going stale at 12 hours is a real emergency. A long-tail catalog card going stale at 30 hours is a Tuesday. One clock treated them the same, so the dashboard cried wolf constantly and hid the actual emergencies inside the noise.
Splitting the clock into lanes
Today's change retires the single 30-hour metric and replaces it with three lane-specific freshness facts, each with its own SLA:
- Portfolio lane: 12h. These are the cards that matter most to a browsing user; staleness here is a user-facing breach.
- Value lane: 24h. Mid-priority cards that drift more but still need to be reasonably current.
- Catalog lane: 7d. The long tail; stale counts stay diagnostic only, not a breach.
The breach function now asks two questions instead of one: are there unmapped portfolio cards (a card exists but has no pricing lane assigned), and are there stale cards within an active lane? Here's the simplified shape of the new check:
// Before: one coarse segment, any breach flips global
function hasBreach(summary) {
return summary.pricing.some(seg => seg.breached) || /* ... */;
}
// After: lane-aware. Unmapped portfolio cards are always a
// breach (we never want an active card with no lane). Stale
// cards are a breach per their lane's own SLA.
function hasBreach(summary) {
return summary.portfolioPricing.some(s => s.unmappedCards > 0)
|| summary.pricingLanes.some(s => s.staleCards > 0)
|| /* sealed, discovery, display-price, outbox, breaker ... */;
}
The old whole-catalog count sticks around as a diagnostic number on the dashboard, but it no longer drives a breach decision. And the six per-game lane stale-card series now feed the workflow dashboard directly, so you can see which game's pricing is actually lagging instead of just "something is stale somewhere."
The part I'm happiest about: unmapped portfolio cards are now an explicit global breach rather than silently falling through. Before, a card with no lane assignment just didn't count toward or against anything. Now it's a hard red. If a card is active in the portfolio, it has to have a lane, full stop.
Everything else (sealed products, discovery, display-price, outbox, breaker, infrastructure-terminal violations) keeps its independent breach behavior. Only the pricing dimension got decomposed; the other freshness checks were already specific enough.