diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index 14107456f..384770387 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -979,3 +979,4 @@ {"id":"int-543d6daae23c869734e3476978a94fb7","kind":"field_change","created_at":"2026-09-18T03:32:32.214406398Z","actor":"luke","issue_id":"teamarr-9yg4","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Replaced the expired fixed date with a window-relative trusted stream date; audited matching tests for comparable calendar coupling."}} {"id":"int-8c07dda1ddd1cabe86b73bc8acf24d84","kind":"field_change","created_at":"2026-09-18T03:41:46.985536441Z","actor":"luke","issue_id":"teamarr-ifqc","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Fixed colon-form NFL schedule prefix parsing; regression test and exact fixture-match reproduction pass."}} {"id":"int-ed0574732b9ae1d8b3360da1014ba17a","kind":"field_change","created_at":"2026-09-19T17:28:28.067773275Z","actor":"luke","issue_id":"teamarr-1i0n","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented orientation-aware tie-breaking with regression coverage; PR pending review."}} +{"id":"int-04c3e31b14db500af9b552c627ca0e08","kind":"field_change","created_at":"2026-09-19T18:39:25.953893355Z","actor":"luke","issue_id":"teamarr-ecug","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented per-league feed separation overrides in PR #TBD."}} diff --git a/frontend/src/api/settings.ts b/frontend/src/api/settings.ts index a397fcbb3..a6bf69e19 100644 --- a/frontend/src/api/settings.ts +++ b/frontend/src/api/settings.ts @@ -660,6 +660,7 @@ export interface SubscriptionLeagueConfig { channel_group_mode: string | null matchup_order: string | null // "auto" | "away_first" | "home_first"; null = global setting included_divisions: string[] | null // #811: null = every division ESPN files under the league + feed_separation_enabled: boolean | null // #862: null = global setting } export interface LeagueDivision { @@ -689,6 +690,7 @@ export async function upsertLeagueConfig( channel_group_mode?: string | null matchup_order?: string | null included_divisions?: string[] | null + feed_separation_enabled?: boolean | null } ): Promise { return api.put(`/league-configs/${encodeURIComponent(leagueCode)}`, data) diff --git a/frontend/src/components/PerLeagueChannelConfig.tsx b/frontend/src/components/PerLeagueChannelConfig.tsx index 74e88f096..16166d4b9 100644 --- a/frontend/src/components/PerLeagueChannelConfig.tsx +++ b/frontend/src/components/PerLeagueChannelConfig.tsx @@ -55,6 +55,7 @@ function LeagueConfigRow({ channel_group_mode?: string | null matchup_order?: string | null included_divisions?: string[] | null + feed_separation_enabled?: boolean | null }) => Promise onClear: () => Promise }) { @@ -62,6 +63,7 @@ function LeagueConfigRow({ const [localGroupId, setLocalGroupId] = useState(null) const [localGroupMode, setLocalGroupMode] = useState(null) const [localMatchupOrder, setLocalMatchupOrder] = useState(null) + const [localFeedSeparationEnabled, setLocalFeedSeparationEnabled] = useState(null) // #811: the divisions still ingested. Held as the checked set (null config = // all of them), so the UI never has to special-case "no override". const [localDivisions, setLocalDivisions] = useState([]) @@ -84,12 +86,14 @@ function LeagueConfigRow({ setLocalGroupId(config.channel_group_id) setLocalGroupMode(config.channel_group_mode) setLocalMatchupOrder(config.matchup_order ?? null) + setLocalFeedSeparationEnabled(config.feed_separation_enabled) setLocalDivisions(config.included_divisions ?? divisions.map((d) => d.key)) } else if (isExpanded && !config) { setLocalProfileIds([]) setLocalGroupId(null) setLocalGroupMode(null) setLocalMatchupOrder(null) + setLocalFeedSeparationEnabled(null) setLocalDivisions(divisions.map((d) => d.key)) } } @@ -134,6 +138,7 @@ function LeagueConfigRow({ channel_group_id: localGroupId, channel_group_mode: localGroupMode, matchup_order: localMatchupOrder, + feed_separation_enabled: localFeedSeparationEnabled, // All of them is stored as "no override" so the selection still means // everything if ESPN's slate gains a division later. included_divisions: @@ -178,6 +183,13 @@ function LeagueConfigRow({ {matchupOrderSummary} + + + {config?.feed_separation_enabled === null || config?.feed_separation_enabled === undefined + ? "Default" + : config.feed_separation_enabled ? "Enabled" : "Disabled"} + + {hasOverride && (