非エンジニアのソロ創業者がFastAPI・SQLite・Claude AIで10言語のスポーツ分析プラットフォームを作った方法

Dev.to / 2026/4/27

💬 オピニオンDeveloper Stack & InfrastructureSignals & Early TrendsTools & Practical UsageIndustry & Market Moves

要点

  • 非エンジニアのソロ創業者が、開発の主要ツールとしてClaude AIを使い、約3週間で「LapScore」を構築した。
  • システムはあえてシンプルに設計されており、FastAPI(Python)とSQLite(WALモード)、Jinja2テンプレート+軽量SPA、Vultr VPSを採用し、PostgreSQLやRedis、マイクロサービス、Kubernetesは使っていない。
  • 「とにかくスケールを優先すべき」という考えには懐疑的で、SQLiteが1日あたりの試合記録(14,358件)と10万超のSEOページ(122,170件)を、実質的に無制限に近い同時リードで処理できると述べている。
  • 予約スケジューラで致命的になりかけた問題は、共有関数のデフォルト引数(時間窓)のせいで、遅い日には朝の予測がすべてスキップされたことに起因し、デフォルト値が「静かな地雷」になり得ると学んだ。
  • SEOについては、1つのJinja2テンプレートを試合×言語(10言語)でレンダリングし、hreflangと大規模なサイトマップをGoogle Search Consoleに送信することで、ロングテールで勝つ戦略を取っている。

私は正式なコーディング経験がまったくないソロ創業者です。それでも、私はClaude AIを主な開発ツールとして使い、約3週間でLapScore――無料のスポーツ分析プラットフォームで、10言語で日次14,000件以上の試合を追跡――を構築しました。

この記事は、スタック、重要な意思決定、そして意外な学びについての透明な技術的内訳です。

スタック(思っているよりずっとシンプル) バックエンド:FastAPI(Python)

データベース:SQLite(WALモード)
テンプレート:Jinja2 + 軽量SPA
サーバー:Vultr VPS(Seoul)
AI:Anthropic Claude
スポーツAPI:api-sports.io

以上です。Postgresなし、Redisなし、マイクロサービスなし、Kubernetesなし。Pythonプロセス1つで、122,170ものSEOページにまたがって14K+の試合を提供しています。

なぜFastAPI + SQLite(Postgresではなく)なのか?

「あらゆるコストでスケールしろ」という助言は、初期段階のプロダクトではだいたい間違っています。

SQLite(WALモード)で対応できたのは:

  • 日次14,358件の試合レコード
  • 122,170件のサーバーサイドレンダリングSEOページ
  • 同時リード(実質的に無制限)
  • 毎分のバックグラウンドジョブによる書き込み

単一ファイルのバックアップ。コネクションプールの設定なし。「データベースが落ちてない?」パニックなし。

LapScoreが実際にPostgresを必要とするのは(10Kの同時書き込みが来たとき)なので、その時になれば判断します。それまでは、SQLiteは制約ではなく機能です。

ほとんど壊したバックグラウンド・スケジューラ

LapScoreはAPSchedulerで1日2回、予測を生成します:

_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
)

昨日、今日分のピックがないことに気づきました。調査の結果、朝の関数で次のようになっていました:


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

デフォルトの hours_ahead_min=4 は「今から4時間以上先に開始する試合だけを考慮する」という意味でした。試合の進みが遅い日には、すべての試合がスキップされてしまいました。

学び:共有関数のデフォルト引数は、静かな地雷になり得ます。

SEO:122Kページを“122Kページ書かずに”作る

私は1つのJinja2テンプレートを生成し、その後、すべての試合 × すべての言語でレンダリングします:/match/lazio-vs-udinese-serie-a-1234 (英語)
/match/lazio-vs-udinese-serie-a-1234?lang=de (ドイツ語)
/match/lazio-vs-udinese-serie-a-1234?lang=pt (ポルトガル語)
... × 10言語

さらに、適切な hreflang タグと、Google Search Consoleに提出した12,437 URLのサイトマップを組み合わせることで、「livescore」(DR 90+の巨大勢がSERPを独占しています)を取りに行こうとするよりも勝てます。

ロングテールが勝つんです。

LAP予測システム

LAPのピックはバーチャルな$1,000の運用資金(バンクロール)とともに公開で追跡しています:

  • 開始:2026-04-22
  • 現在:$1,103.72(+10.37% ROI)
  • 勝率:60%(15/25)

すべてのピック。すべての結果。削除なし。

Claude APIは日次50〜100の試合を分析し、エッジ >8% を探し、自信があるときだけ公開します。ある日は6ピック出ますが、ある日は2ピックです。そこが狙いです。

Claudeと一緒に働くと実際どうなるか

私はコードを書きません。やりたいことを説明し、エラーを貼り付け、ログを貼り付けて、反復します。

典型的なやり取り:

  • 私:「今朝のピックが今日生成されていません。ログはこちら:[貼り付け]」
  • Claude:「hours_ahead_min=4 のデフォルトが全部をフィルタリングしてます。修正:[コード]」
  • 私:SSHで入り、修正を貼り付け、動作確認して、再デプロイ。

これが機能する理由:

  1. プロダクトを冷静に理解している(何が起きるべきで、何が起きてはいけないか)
  2. コードを読むことはできる(最初から書けないとしても)
  3. 徹底的にバックアップしている(変更のたびに *.bak_YYYYMMDD_HHMMSS

非技術者だからといって無関係ではありません。私は、構文の知識をプロダクトの明瞭さと交換しているだけです。

真の倍率(マルチプライヤー)

3週間の開発の後、最も重要だったのは技術ではなく、次のようなことでした:

  1. 公開バンクロール追跡――過激な透明性がマーケティング主張に勝つ
  2. 初日から10言語――多くのスポーツサイトは英語のみ、または単一ロケールだけ
  3. 無料・サインアップ不要――導入の摩擦は、UXの悪さよりも速く採用を殺す
  4. ロングテールSEO――競争の少ない試合コンテンツの122Kページ

スタック自体はほとんど重要ではありません。重要なのは、それをめぐる意思決定です。

ぜひ試してみてください

LapScore――10言語で楽しめる無料のスポーツスコアと予測。

LAP Pick Bankroll――公開のROIトラッカー。

もしあなたが、AIの支援を受けながら何かをソロで作っているなら、どんなスタックを使っているかぜひ聞かせてください。コメントしてください。