Building a Fantasy Baseball Analytics App with Claude Code: A Law Student's Experience

A Navy veteran and law student with a 2017 computer science degree who hadn't touched code since graduation built a complete fantasy baseball analytics iOS app called Ball Knower using Claude Code for implementation while making all product and domain decisions. The app is live on the App Store and was developed during the student's final year of law school.
What Was Built
Ball Knower is a fantasy baseball analytics app that includes:
- 1,313 MLB player profiles with Statcast percentile bars (color-coded bars from Baseball Savant)
- Daily streaming pitcher picks scored 0-100
- Keep-Trade-Cut dynasty rankings with ELO scoring
- 1,241 MLB players + 72 FanGraphs prospects
- 87 distinct metrics tracked per player
Technical Stack
Frontend: SwiftUI (iOS 17+), Swift Charts, StoreKit 2
Backend: Python 3.12, FastAPI, SQLAlchemy async, PostgreSQL, Redis, APScheduler
Infrastructure: Single DigitalOcean droplet, Docker
Data Sources: 30 scheduled jobs pulling from MLB Stats API, Baseball Savant via pybaseball, ESPN RSS, The Odds API, and Open-Meteo weather
Where Claude Code Excelled
- Wired a FastAPI dependency injection chain to an async SQLAlchemy session to a Redis cache layer in minutes (would have taken days from documentation alone)
- Debugged an async race condition in the subscription validation flow where the refresh token coordinator and StoreKit 2 listener were conflicting
- Identified the problem and wrote an actor-based fix after being described the symptoms
- Wrote approximately 70% of the raw lines of code
Where Claude Code Fell Short
- Mapped 85% of data source columns correctly, but 15% returned nil silently with no errors or crashes
- Missed column name mismatches (e.g., pybaseball returns brl_percent while database column was barrel_pct)
- Confidently generated code requesting App Tracking Transparency permission for non-personalized ads, causing Apple to reject the build
- Generated SwiftUI modifier chains that compiled but rendered incorrectly on edge cases
- Used deprecated API patterns without mentioning they were deprecated
Developer's Role
The developer wrote or corrected the remaining 30% of code, which included:
- Scoring algorithm weights
- Cache invalidation logic
- Subscription flow
- Data column mappings
- App Store compliance
- Domain-specific decisions (dome stadiums don't have wind, spring training stats shouldn't weight equally, Baseball Savant's percentile API requires gap-fill logic for non-qualified players)
Development Metrics
- 300+ development hours across one semester
- 30 automated cron jobs running nightly starting 2:25 AM ET
- 9 external data sources synced daily
- 2 App Store rejections before acceptance (EULA labeling + unnecessary ATT permission)
- Break-even: 13 subscribers at $3.99/month
📖 Read the full source: r/ClaudeAI
👀 See Also

Managing AI Agent Failures: Retry Limits and Failure Budgets
A production team running 6 AI agents implemented a 3-strike failure budget after an agent retried a rate-limited task 319 times, burning hours of compute. They also addressed heartbeat timeouts, false task completion reports, and optimistic locking conflicts.

Using Claude Code for Go-to-Market Operations: Context Engineering Patterns
A developer shares practical patterns for using Claude Code beyond coding, specifically for running go-to-market operations including scraping, enrichment, databases, email infrastructure, and multi-platform content. Key techniques include CLAUDE.md files, session scoping, CLI tools over MCP servers, and subagents for heavy lifting.

Practical Criticism of LLM Memory: Immutable Reflections & Ephemeral Sessions as Solutions
A critique of long-running sessions, life-companions, and LLM-wiki memory, offering solutions like immutable reflections, issue-bound session chains, and prompt templates to avoid intent loss and context overload.

Reducing AI Agent Context Bloat with Single Workspace Architecture
A developer shares how they reduced AI assistant startup context from 27,000 to 4,000 tokens by implementing a single workspace approach instead of complex agent swarms, using channel-level identity injection and segregated memory folders.