sba-scouting/PROJECT_PLAN.json
Cal Corum 9863f89309 Implement Standings screen with DB-cached two-phase loading
Add league standings with Division and Wild Card tabs, fetched from API
with SQLite cache for instant display on screen open. Document 11 new
future features in project plan and add cargo check post-edit hook.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:31:55 -06:00

597 lines
29 KiB
JSON

{
"meta": {
"version": "1.0.0",
"created": "2026-01-25",
"lastUpdated": "2026-03-01",
"planType": "feature",
"project": "SBA Scout TUI",
"description": "Fantasy baseball scouting TUI application for the SBA (Strat-o-Matic Baseball Association) league",
"totalEstimatedHours": 82,
"totalTasks": 29,
"completedTasks": 8
},
"categories": {
"critical": "Must fix immediately - blocks core functionality",
"high": "Required for production-ready app",
"medium": "Quality improvements and secondary features",
"low": "Polish, nice-to-have features",
"feature": "New capabilities and screens"
},
"tasks": [
{
"id": "FEAT-001",
"name": "Dashboard Screen",
"description": "Main dashboard showing roster summary (Majors/Minors/IL counts), sWAR usage, and quick navigation buttons",
"category": "feature",
"priority": 1,
"completed": true,
"tested": true,
"dependencies": [],
"files": [
{
"path": "src/sba_scout/app.py",
"lines": [30, 180],
"issue": "DashboardScreen class implementation"
}
],
"suggestedFix": null,
"estimatedHours": 4,
"notes": "Completed - shows roster counts and sWAR from settings"
},
{
"id": "FEAT-002",
"name": "Roster Screen",
"description": "Full roster view with tabbed display (Majors/Minors/IL), separate DataTables for batters and pitchers with ratings and stats",
"category": "feature",
"priority": 2,
"completed": true,
"tested": true,
"dependencies": ["FEAT-001"],
"files": [
{
"path": "src/sba_scout/screens/roster.py",
"lines": [1, 270],
"issue": "RosterScreen implementation"
}
],
"suggestedFix": null,
"estimatedHours": 6,
"notes": "Completed - batters show vL/vR/Ovr/Defense, pitchers show vL/vR/Ovr/S/R/C endurance"
},
{
"id": "FEAT-003",
"name": "Card Data Importer",
"description": "Import batter and pitcher card data from BatterCalcs.csv and PitcherCalcs.csv exports, including pre-calculated ratings",
"category": "feature",
"priority": 1,
"completed": true,
"tested": true,
"dependencies": [],
"files": [
{
"path": "src/sba_scout/api/importer.py",
"lines": [1, 400],
"issue": "CSV import functions"
}
],
"suggestedFix": null,
"estimatedHours": 4,
"notes": "Completed - imports vL/vR/Total ratings directly from spreadsheet"
},
{
"id": "FEAT-004",
"name": "API Sync",
"description": "Sync players, teams, and transactions from Major Domo league API",
"category": "feature",
"priority": 2,
"completed": true,
"tested": true,
"dependencies": [],
"files": [
{
"path": "src/sba_scout/api/client.py",
"lines": [1, 150],
"issue": "API client implementation"
},
{
"path": "src/sba_scout/api/sync.py",
"lines": [1, 200],
"issue": "Sync logic"
}
],
"suggestedFix": null,
"estimatedHours": 4,
"notes": "Completed - syncs from league API on demand"
},
{
"id": "FEAT-005",
"name": "Matchup Scout Screen",
"description": "Core scouting feature - analyze batter vs pitcher matchups, show expected outcomes based on handedness splits",
"category": "feature",
"priority": 3,
"completed": true,
"tested": true,
"dependencies": ["FEAT-002", "FEAT-003"],
"files": [
{
"path": "src/sba_scout/screens/matchup.py",
"lines": [1, 290],
"issue": "Full implementation complete"
},
{
"path": "src/sba_scout/calc/matchup.py",
"lines": [1, 130],
"issue": "Matchup calculation logic"
}
],
"suggestedFix": null,
"estimatedHours": 8,
"notes": "Implemented: team/pitcher selectors, matchup table with rating/tier, sort by rating/name/position, switch hitter logic (uses opposite of pitcher hand)"
},
{
"id": "FEAT-006",
"name": "Lineup Builder Screen",
"description": "Set batting order and defensive positions, save/load lineup configurations",
"category": "feature",
"priority": 4,
"completed": true,
"tested": true,
"dependencies": ["FEAT-002"],
"files": [
{
"path": "src/sba_scout/screens/lineup.py",
"lines": [1, 450],
"issue": "Full implementation complete"
}
],
"suggestedFix": null,
"estimatedHours": 6,
"notes": "Implemented: dual-panel UI with available batters and lineup tables, keyboard navigation (a=add, r=remove, k/j=move up/down, p=cycle position), save/load named lineups, position eligibility suggestions"
},
{
"id": "FEAT-007",
"name": "Transactions Screen",
"description": "View recent transactions, track player movements, manage roster moves",
"category": "feature",
"priority": 5,
"completed": false,
"tested": false,
"dependencies": ["FEAT-004"],
"files": [
{
"path": "src/sba_scout/app.py",
"lines": [234, 249],
"issue": "Placeholder TransactionsScreen needs implementation"
}
],
"suggestedFix": "1. Create src/sba_scout/screens/transactions.py\n2. Show recent league transactions\n3. Filter by team, player, date\n4. Show demotion weeks for minors players\n5. Highlight players who can be promoted",
"estimatedHours": 4,
"notes": "Transaction model already exists, needs UI"
},
{
"id": "FEAT-008",
"name": "Depth Chart Screen (by Position)",
"description": "View roster organized by defensive position showing depth at each spot",
"category": "feature",
"priority": 6,
"completed": false,
"tested": false,
"dependencies": ["FEAT-002"],
"files": [],
"suggestedFix": "1. Create src/sba_scout/screens/depth_chart.py\n2. Show positions as columns or tabs (C, 1B, 2B, SS, 3B, LF, CF, RF, DH)\n3. List eligible players at each position\n4. Show defensive ratings (range, error, arm)\n5. Highlight primary vs secondary positions",
"estimatedHours": 4,
"notes": "Different from Roster screen - organized by position rather than roster status"
},
{
"id": "FEAT-009",
"name": "Player Overview Popup",
"description": "Global player overview popup accessible from any screen that displays a player name. Press a hotkey (e.g. Enter or 'i') on any highlighted player row to open a floating overlay showing full card details, stats, and ratings breakdown. Must work consistently across Dashboard, Roster, Matchup, Lineup, Gameday, and any future screens.",
"category": "feature",
"priority": 7,
"completed": false,
"tested": false,
"dependencies": ["FEAT-002"],
"files": [],
"suggestedFix": "1. Create a reusable PlayerOverlay widget in src/widgets/player_overlay.rs\n2. Show full batter card (all vs LHP and vs RHP columns, OBP/SLG/OPS, power, eye, speed)\n3. Show full pitcher card (all vs LHB and vs RHB columns, endurance S/R/C, hold rating)\n4. Show fielding details at each eligible position (range, error, arm, T-rating)\n5. Show running game stats (stealing, speed, bunt)\n6. Render as a centered floating panel with Esc to dismiss\n7. Wire the hotkey into App-level key handling so it works from any screen with a selected player",
"estimatedHours": 5,
"notes": "Universal access is key — this should be an App-level overlay, not per-screen logic. Each screen just needs to expose a 'currently selected player ID' method."
},
{
"id": "HIGH-001",
"name": "Dynamic Season Configuration",
"description": "Remove hardcoded season 13, get current season from config or API",
"category": "high",
"priority": 8,
"completed": true,
"tested": true,
"dependencies": [],
"files": [
{
"path": "src/sba_scout/app.py",
"lines": [116],
"issue": "Hardcoded season=13 in dashboard"
},
{
"path": "src/sba_scout/screens/roster.py",
"lines": [138],
"issue": "Hardcoded season=13 in roster"
},
{
"path": "src/sba_scout/api/client.py",
"lines": [32],
"issue": "Example uses season=13"
}
],
"suggestedFix": "1. Add current_season to TeamSettings in config.py\n2. Update .env.example with SBA_SCOUT_TEAM__CURRENT_SEASON=13\n3. Replace all hardcoded 13 with settings.team.current_season\n4. Optionally: fetch current season from league API",
"estimatedHours": 1,
"notes": "Quick fix but important for multi-season support"
},
{
"id": "MED-001",
"name": "Schedule Integration",
"description": "Show upcoming games, opponent info, and starting pitchers",
"category": "medium",
"priority": 9,
"completed": false,
"tested": false,
"dependencies": ["FEAT-004"],
"files": [],
"suggestedFix": "1. Add schedule endpoint to API client\n2. Create Schedule model in database\n3. Add upcoming games widget to dashboard\n4. Link to Matchup Scout with opponent pre-selected",
"estimatedHours": 4,
"notes": "Would enhance dashboard and matchup workflow"
},
{
"id": "MED-002",
"name": "Rating Recalculation Engine",
"description": "Rebuild rating calculation system for matchup analysis (was removed, needs fresh implementation)",
"category": "medium",
"priority": 10,
"completed": false,
"tested": false,
"dependencies": ["FEAT-005"],
"files": [
{
"path": "src/sba_scout/calc/__init__.py",
"lines": [],
"issue": "calc module is empty after removing ratings.py and matchup.py"
}
],
"suggestedFix": "1. Design new calculation approach based on matchup needs\n2. Consider: should matchups combine batter vL + pitcher vRHB?\n3. Implement matchup_score = f(batter_rating, pitcher_rating, handedness)\n4. Add tier system (A/B/C/D/F) for quick reference",
"estimatedHours": 4,
"notes": "Original calc was removed because roster ratings come pre-calculated from spreadsheet. Matchup calculations need different logic."
},
{
"id": "MED-003",
"name": "Keyboard Navigation Enhancement",
"description": "Add vim-style navigation, better hotkeys, command palette",
"category": "medium",
"priority": 11,
"completed": false,
"tested": false,
"dependencies": [],
"files": [],
"suggestedFix": "1. Add j/k navigation in tables\n2. Add search/filter with / key\n3. Implement command palette (ctrl+p)\n4. Add goto player by name",
"estimatedHours": 2,
"notes": "TUI apps benefit greatly from keyboard-first design"
},
{
"id": "MED-004",
"name": "Auto-Sync on Startup",
"description": "Optionally sync data from API when app starts, with configurable interval",
"category": "medium",
"priority": 12,
"completed": false,
"tested": false,
"dependencies": ["FEAT-004"],
"files": [
{
"path": "src/sba_scout/config.py",
"lines": [126, 129],
"issue": "refresh_interval setting exists but not implemented"
}
],
"suggestedFix": "1. Check last_sync timestamp on startup\n2. If stale (> refresh_interval), trigger sync\n3. Show sync status in dashboard\n4. Add background sync timer (optional)",
"estimatedHours": 2,
"notes": "refresh_interval setting already exists in config"
},
{
"id": "LOW-001",
"name": "Theme Support",
"description": "Light/dark theme toggle using Textual's theming system",
"category": "low",
"priority": 13,
"completed": false,
"tested": false,
"dependencies": [],
"files": [
{
"path": "src/sba_scout/config.py",
"lines": [129],
"issue": "theme setting exists but not implemented"
}
],
"suggestedFix": "1. Use Textual's built-in theme system\n2. Add theme toggle hotkey (t)\n3. Persist theme preference in config",
"estimatedHours": 1,
"notes": "theme setting already exists in config"
},
{
"id": "LOW-002",
"name": "Export Functionality",
"description": "Export lineups, matchup reports, or roster data to various formats",
"category": "low",
"priority": 14,
"completed": false,
"tested": false,
"dependencies": ["FEAT-005", "FEAT-006"],
"files": [],
"suggestedFix": "1. Export lineup to clipboard (for pasting into game)\n2. Export matchup report to markdown/text\n3. Export roster to CSV",
"estimatedHours": 2,
"notes": "Clipboard export would be most immediately useful"
},
{
"id": "LOW-003",
"name": "Draft Tools",
"description": "Tools for evaluating players during the draft",
"category": "low",
"priority": 15,
"completed": false,
"tested": false,
"dependencies": ["FEAT-003"],
"files": [],
"suggestedFix": "1. Player search across all teams\n2. Compare players side-by-side\n3. Track draft queue/watchlist\n4. sWAR value analysis",
"estimatedHours": 6,
"notes": "Would be valuable during draft season"
},
{
"id": "TEST-001",
"name": "Add Unit Tests",
"description": "Create test suite for core functionality",
"category": "medium",
"priority": 16,
"completed": false,
"tested": false,
"dependencies": [],
"files": [
{
"path": "tests/__init__.py",
"lines": [],
"issue": "Tests directory is empty"
}
],
"suggestedFix": "1. Test importer with sample CSV data\n2. Test database queries\n3. Test API client with mocked responses\n4. Test config loading",
"estimatedHours": 4,
"notes": "Focus on data layer tests first"
},
{
"id": "FEAT-010",
"name": "Waiver Wire / Free Agent Browser",
"description": "Browse all unrostered players across the league, sorted by rating. Filter by position, handedness, and rating tier. Essential for finding replacements mid-season when a roster gap opens up.",
"category": "feature",
"priority": 17,
"completed": false,
"tested": false,
"dependencies": ["FEAT-004", "FEAT-003"],
"files": [],
"suggestedFix": "1. Create src/screens/waiver_wire.rs\n2. Query all players not on any team's major league roster\n3. Display with card ratings (vL/vR/Ovr), position eligibility, and tier\n4. Add filters: position dropdown, handedness toggle, min rating threshold\n5. Sort by overall rating, vL, vR, or position\n6. Add hotkey to jump directly to Player Overview popup for deeper look\n7. Consider adding a 'watchlist' save feature for tracking targets",
"estimatedHours": 5,
"notes": "Depends on API exposing all league players, not just your team. Check if the sync pipeline already pulls all teams' rosters."
},
{
"id": "FEAT-011",
"name": "Trade Evaluator",
"description": "Side-by-side comparison tool for evaluating potential trades. Select players from your roster and an opponent's roster to compare sWAR, ratings, position scarcity, and contract value. Not AI-powered — just structured data presentation to inform trade decisions.",
"category": "feature",
"priority": 18,
"completed": false,
"tested": false,
"dependencies": ["FEAT-002", "FEAT-003"],
"files": [],
"suggestedFix": "1. Create src/screens/trade_eval.rs\n2. Two-panel layout: 'My Players' (left) vs 'Their Players' (right)\n3. Select opponent team, then pick players from each side\n4. Show per-player: name, position(s), vL/vR/Ovr, sWAR, contract/salary if available\n5. Show aggregate comparison: total sWAR, position coverage gained/lost\n6. Highlight position scarcity impact (losing your only SS vs trading from OF depth)\n7. Allow saving trade scenarios for later review",
"estimatedHours": 5,
"notes": "Keep it simple — structured comparison, no valuation algorithm needed. The human makes the judgment call."
},
{
"id": "FEAT-012",
"name": "Bullpen Usage Planner",
"description": "Plan bullpen deployment for a game based on pitcher endurance ratings (S/R/C), handedness, and the opposing lineup's handedness mix. Strat-o-Matic bullpen management is nuanced — this screen helps optimize usage.",
"category": "feature",
"priority": 19,
"completed": false,
"tested": false,
"dependencies": ["FEAT-002", "FEAT-005"],
"files": [],
"suggestedFix": "1. Create src/screens/bullpen.rs\n2. Show all pitchers with role (SP/RP/CL), endurance (S/R/C), handedness, vLHB/vRHB ratings\n3. Select opposing lineup to see handedness breakdown (how many LHB vs RHB)\n4. Suggest optimal bullpen order: closer, setup, long relief, mop-up\n5. Show fatigue/availability indicators if usage tracking data is available\n6. Highlight platoon advantages (bring in LHP vs cluster of RHB in lineup)",
"estimatedHours": 4,
"notes": "Could integrate with the Gameday screen as a bullpen tab, or be standalone."
},
{
"id": "FEAT-013",
"name": "Fuzzy Search / Command Palette",
"description": "Global fuzzy search overlay (Ctrl+P or /) that lets you jump to any player, team, or screen by typing. Searches across all player names, team names, and screen names with ranked fuzzy matching. Massive TUI productivity boost.",
"category": "feature",
"priority": 20,
"completed": false,
"tested": false,
"dependencies": [],
"files": [],
"suggestedFix": "1. Create src/widgets/command_palette.rs as a floating overlay\n2. Bind to Ctrl+P or / at the App level\n3. Index: all player names (with team), all team names, all screen names\n4. Fuzzy match using a simple substring/prefix scorer (or nucleo/fuzzy-matcher crate)\n5. Show results ranked by match quality with type indicators ([Player] [Team] [Screen])\n6. Enter on a player opens the Player Overview popup\n7. Enter on a team navigates to Roster filtered to that team\n8. Enter on a screen navigates to that screen\n9. Esc dismisses without action",
"estimatedHours": 4,
"notes": "Consider the nucleo crate for fuzzy matching. Keep it simple — even basic substring matching is useful."
},
{
"id": "FEAT-014",
"name": "Notifications / Alerts Panel",
"description": "Surface actionable items that need attention: players eligible to come off IL, minor leaguers past their demotion window eligible for promotion, new transactions affecting your team, upcoming roster deadlines. Could be a dashboard widget or a dedicated panel.",
"category": "feature",
"priority": 21,
"completed": false,
"tested": false,
"dependencies": ["FEAT-004", "FEAT-007"],
"files": [],
"suggestedFix": "1. Create src/widgets/alerts.rs for the alert display component\n2. Alert types: IL_ELIGIBLE (player can come off IL), PROMOTION_ELIGIBLE (minors demotion weeks served), TRANSACTION_ALERT (new trade/waiver affecting your team), ROSTER_DEADLINE (upcoming deadline)\n3. Compute alerts on sync or mount from DB data\n4. Show count badge in nav bar or dashboard\n5. Clicking an alert navigates to the relevant screen/player\n6. Allow dismissing alerts",
"estimatedHours": 4,
"notes": "Requires transaction and roster status data to compute alerts. Some alerts may need API data not yet synced (like schedule deadlines)."
},
{
"id": "FEAT-015",
"name": "Clipboard Lineup Export",
"description": "Copy a built lineup to the system clipboard in the exact format needed for league submission or Discord posting. Eliminates manual transcription of lineup data — the 'last mile' feature that saves real time every game day.",
"category": "feature",
"priority": 22,
"completed": false,
"tested": false,
"dependencies": ["FEAT-006"],
"files": [],
"suggestedFix": "1. Add a 'copy to clipboard' hotkey (e.g. Ctrl+C or 'y') to the Lineup and Gameday screens\n2. Format lineup as plain text: batting order with position and player name\n3. Use the arboard or cli-clipboard crate for cross-platform clipboard access\n4. Show a notification confirming the copy\n5. Consider multiple export formats: plain text, Discord markdown table, league submission format\n6. Optionally include matchup ratings in the export for Discord scouting posts",
"estimatedHours": 2,
"notes": "Small feature, huge time savings. arboard crate works on Linux/Mac/Windows."
},
{
"id": "FEAT-016",
"name": "Standings / League Overview",
"description": "Display current league standings with W-L records, division/conference breakdowns, and optionally strength-of-schedule indicators. Provides context for scouting decisions — knowing where teams sit affects trade and waiver strategy.",
"category": "feature",
"priority": 23,
"completed": true,
"tested": true,
"dependencies": ["FEAT-004"],
"files": [],
"suggestedFix": "1. Create src/screens/standings.rs\n2. Add standings endpoint to API client (or compute from game results if available)\n3. Show table: Team, W, L, Pct, GB, Streak, Last 10\n4. Group by division/conference if the league uses them\n5. Highlight your team's row\n6. Add nav hotkey (e.g. 'w' for standings)\n7. Optional: strength of remaining schedule based on opponent records",
"estimatedHours": 3,
"notes": "Depends on whether the Major Domo API exposes standings data. May need a new sync endpoint."
},
{
"id": "FEAT-017",
"name": "Position Scarcity Index",
"description": "Analyze how your roster depth at each defensive position compares to the league average. Helps prioritize draft picks, trades, and waiver claims by quantifying where you're deep and where you're thin.",
"category": "feature",
"priority": 24,
"completed": false,
"tested": false,
"dependencies": ["FEAT-002", "FEAT-004"],
"files": [],
"suggestedFix": "1. Could be a widget on Dashboard or a tab in the Depth Chart screen\n2. For each position: count eligible players on your roster vs league average\n3. Show quality depth: how many A/B-tier players you have at each position\n4. Color code: green (deep), yellow (adequate), red (thin)\n5. Factor in multi-position eligibility (a player covering SS+2B helps both)\n6. Show league-wide scarcity: positions where few quality players exist across all teams",
"estimatedHours": 3,
"notes": "Builds naturally on the Depth Chart screen (FEAT-008). Could share a screen or be a dashboard widget."
},
{
"id": "FEAT-018",
"name": "What-If Roster Simulator",
"description": "Temporarily add or remove players from your roster to preview how sWAR, position coverage, depth chart, and overall team composition would change. Essential for evaluating trade and waiver scenarios before committing.",
"category": "feature",
"priority": 25,
"completed": false,
"tested": false,
"dependencies": ["FEAT-002", "FEAT-008"],
"files": [],
"suggestedFix": "1. Create src/screens/simulator.rs or add a 'simulate' mode to existing screens\n2. Start with current roster as baseline\n3. Allow adding players from other teams (search/select) and removing your own\n4. Show before/after comparison: total sWAR, position coverage grid, depth chart diff\n5. Highlight what improves and what gets worse\n6. Allow saving simulation scenarios with names for later comparison\n7. Do NOT modify the actual database — all changes are in-memory only",
"estimatedHours": 5,
"notes": "Must be clearly marked as simulation — never write simulated changes to DB. Could reuse trade evaluator components."
},
{
"id": "FEAT-019",
"name": "Pitcher Matchup Heatmap",
"description": "Visual TUI representation of how each batter fares against a specific pitcher's card, broken down by result type (HR, 2B, 3B, 1B, BB, K, GO, FO) rather than just a composite score. Uses colored cells to show hot/cold zones across the result distribution.",
"category": "feature",
"priority": 26,
"completed": false,
"tested": false,
"dependencies": ["FEAT-005", "FEAT-003"],
"files": [],
"suggestedFix": "1. Create src/widgets/heatmap.rs for the colored-cell grid renderer\n2. For a selected pitcher, show each batter as a row\n3. Columns: HR%, XBH%, 1B%, BB%, K%, GO%, FO% (derived from card data)\n4. Color cells: green (favorable) through yellow to red (unfavorable) relative to league averages\n5. Could be a mode/tab within the Matchup screen rather than a separate screen\n6. Allow toggling between composite score view and heatmap view\n7. Use Unicode block characters or background colors for the heat visualization",
"estimatedHours": 4,
"notes": "Requires granular card result data beyond just vL/vR composite ratings. Check if BatterCalcs/PitcherCalcs CSVs contain per-result breakdowns."
},
{
"id": "FEAT-020",
"name": "UI Overhaul",
"description": "Comprehensive visual refresh of the entire TUI. Establish a consistent design system with unified color palette, spacing, borders, header styles, and widget patterns across all screens. Current screens were built incrementally — this pass unifies the look and feel into a polished, cohesive application.",
"category": "feature",
"priority": 27,
"completed": false,
"tested": false,
"dependencies": [],
"files": [],
"suggestedFix": "1. Define a theme/style module in src/theme.rs with named colors, border styles, and layout constants\n2. Standardize screen layout: consistent nav bar, status bar, content area margins\n3. Unify table styles: header row colors, alternating row backgrounds, selection highlight\n4. Consistent use of borders (rounded vs sharp), padding, and spacing\n5. Standardize popup/overlay styling (selector, player overview, command palette)\n6. Add screen transition polish (clear rendering, no flicker)\n7. Review color choices for accessibility (sufficient contrast, colorblind-friendly tier colors)\n8. Ensure consistent key hint bar format across all screens\n9. Test at multiple terminal sizes (80x24 minimum, wide/tall layouts)\n10. Consider adding a compact mode for smaller terminals",
"estimatedHours": 6,
"notes": "Best done after most feature screens exist, so the design system covers all cases. Should touch every screen file but the changes are primarily render() methods and style constants."
}
],
"quickWins": [
{
"taskId": "HIGH-001",
"estimatedMinutes": 30,
"impact": "Removes hardcoded season number, enables multi-season support"
},
{
"taskId": "LOW-001",
"estimatedMinutes": 30,
"impact": "Light theme option for users who prefer it"
}
],
"productionBlockers": [],
"weeklyRoadmap": {
"week1": {
"theme": "Core Scouting Features",
"tasks": ["HIGH-001", "FEAT-005"],
"estimatedHours": 9,
"description": "Fix hardcoded season, implement Matchup Scout screen"
},
"week2": {
"theme": "Lineup Management",
"tasks": ["FEAT-006", "FEAT-009"],
"estimatedHours": 10,
"description": "Lineup Builder screen and Player Detail modal"
},
"week3": {
"theme": "Secondary Features",
"tasks": ["FEAT-007", "FEAT-008", "MED-002"],
"estimatedHours": 12,
"description": "Transactions, Depth Chart, and matchup calculations"
},
"week4": {
"theme": "Polish and Testing",
"tasks": ["MED-003", "MED-004", "TEST-001"],
"estimatedHours": 8,
"description": "Keyboard navigation, auto-sync, and unit tests"
}
},
"completedHistory": [
{
"taskId": "FEAT-001",
"completedDate": "2026-01-25",
"notes": "Dashboard with roster summary and navigation"
},
{
"taskId": "FEAT-002",
"completedDate": "2026-01-25",
"notes": "Roster screen with batters/pitchers tables, proper ratings from CSV"
},
{
"taskId": "FEAT-003",
"completedDate": "2026-01-25",
"notes": "CSV importer using pre-calculated vL/vR/Total from spreadsheet"
},
{
"taskId": "FEAT-004",
"completedDate": "2026-01-25",
"notes": "API sync for players and teams from Major Domo"
},
{
"taskId": "HIGH-001",
"completedDate": "2026-01-25",
"notes": "Added current_season to TeamSettings config; replaced hardcoded season=13 in app.py and roster.py"
},
{
"taskId": "FEAT-005",
"completedDate": "2026-01-25",
"notes": "Matchup Scout screen with team/pitcher selection, matchup table showing batter ratings vs pitcher handedness, sorting options, tier grades (A-F)"
},
{
"taskId": "FEAT-006",
"completedDate": "2026-01-25",
"notes": "Lineup Builder screen with dual-panel UI (available batters + lineup), keyboard controls (a=add, r=remove, k/j=reorder, p=change position), save/load named lineups"
}
]
}