DEV Community

LapScore
LapScore

Posted on

How I Built a 10-Language Sports Analytics Platform with FastAPI, SQLite, and Claude AI (As a Solo Non-Technical Founder)

I'm a solo founder with zero formal coding background. Yet, I built LapScore — a free sports analytics platform tracking 14,000+ daily matches in 10 languages — in about 3 weeks using Claude AI as my primary development tool.

This post is a transparent technical breakdown of the stack, key decisions, and surprising lessons.

The Stack (Simpler Than You'd Think)Backend: FastAPI (Python)

Database: SQLite (WAL mode)
Templates: Jinja2 + lightweight SPA
Server: Vultr VPS (Seoul)
AI: Anthropic Claude
Sports API: api-sports.io

That's it. No Postgres, no Redis, no microservices, no Kubernetes. One Python process serving 14K+ matches across 122,170 SEO pages.

Why FastAPI + SQLite (and not Postgres)?

The "scale at all costs" advice is mostly wrong for early-stage products.

SQLite with WAL mode handles:

  • 14,358 daily match records
  • 122,170 server-rendered SEO pages
  • Concurrent reads (essentially unlimited)
  • Background jobs writing every minute

Single-file backups. No connection pool config. No "is the database down?" panics.

When LapScore actually needs Postgres (10K concurrent writes), I'll know. Until then, SQLite is a feature, not a limitation.

The Background Scheduler That Almost Broke

LapScore generates predictions twice daily via APScheduler:

_scheduled_lappick_morning,
'cron', hour=1, minute=0, id='lappick_morning'  # KST 10:00
)
scheduler.add_job(
_scheduled_lappick_evening,
'cron', hour=13, minute=0, id='lappick_evening'  # KST 22:00
)

Yesterday I noticed today's picks were missing. Diagnosis revealed the morning function had:

Enter fullscreen mode Exit fullscreen mode


pythonBug
await generate_daily_lappick(hours_ahead=0, max_picks=3, job_name="morning")Fix (added hours_ahead_min=2)
await generate_daily_lappick(hours_ahead=0, max_picks=3,
job_name="morning", hours_ahead_min=2)

Default hours_ahead_min=4 meant "only consider matches starting 4+ hours from now." On a slow match day, every match got skipped.

Lesson: Default parameters in shared functions are silent bombs.

SEO: 122K Pages Without Writing 122K Pages

I generate one Jinja2 template, then render it for every match × every language:/match/lazio-vs-udinese-serie-a-1234 (English)
/match/lazio-vs-udinese-serie-a-1234?lang=de (German)
/match/lazio-vs-udinese-serie-a-1234?lang=pt (Portuguese)
... × 10 languages

Combined with proper hreflang tags and a 12,437-URL sitemap submitted to Google Search Console, this beats trying to compete for "livescore" (DR 90+ giants own that SERP).

Long-tail wins.

The LAP Prediction System

LAP picks are tracked publicly with a virtual $1,000 bankroll:

  • Started: 2026-04-22
  • Current: $1,103.72 (+10.37% ROI)
  • Win rate: 60% (15/25)

Every pick. Every result. No deletions.

The Claude API analyzes 50-100 daily matches, looks for edge >8%, and publishes only when confident. Some days produce 6 picks, some days produce 2. That's the point.

What Working with Claude Actually Looks Like

I don't write code. I describe what I want, paste errors, paste logs, and iterate.

A typical exchange:

  • Me: "The morning picks didn't generate today. Here's the log: [paste]"
  • Claude: "The hours_ahead_min=4 default is filtering out everything. Fix: [code]"
  • Me: I SSH in, paste the fix, verify, redeploy.

This works because:

  1. I know my product cold (what should happen, what shouldn't)
  2. I can read code even though I can't write it from scratch
  3. I keep extensive backups (*.bak_YYYYMMDD_HHMMSS for every change)

Non-technical doesn't mean uninvolved. It means I trade syntax knowledge for product clarity.

The Real Multipliers

After 3 weeks of building, the things that mattered most weren't technical:

  1. Public bankroll tracking — radical transparency beats marketing claims
  2. 10 languages from day one — most sports sites are English-only or single-locale
  3. Free, no signup — friction kills adoption faster than bad UX
  4. Long-tail SEO — 122K pages of low-competition match content

The stack barely matters. The decisions around it do.


Try It

LapScore — Free sports scores and predictions in 10 languages.

LAP Pick Bankroll — Public ROI tracker.

If you're a solo founder building something with AI assistance, I'd love to hear what stack you're using. Drop a comment.

Top comments (0)