📊

売上予測WebアプリをFastAPI + Prophet + Reactで個人開発してリリースした話

に公開

はじめに

売上・需要予測ができるWebアプリ「SalesCast」を個人で作りました。

https://salescast.vercel.app

機械学習(Prophet)をバックエンドに持ち、CSVを貼り付けるだけで予測グラフが出るシンプルなツールです。技術構成・開発の流れ・詰まったところをまとめます。


背景

需要予測は実務で使われる技術ですが、既存ツールは高額だったり導入ハードルが高かったりします。「CSVを貼れば予測できる」ツールを個人でも作れると思い、開発しました。


技術構成

レイヤー 使用技術
フロントエンド React(Vite) + Recharts
バックエンド FastAPI(Python)
予測エンジン Prophet(Meta製)
インフラ Vercel + Render

なぜProphetか

Prophetは季節性・祝日効果を自動でモデルに組み込んでくれるため、パラメータチューニングが少なくて済みます。「CSVを受け取って予測にそのまま流す」というシンプルな設計と相性が良かったです。


主な機能

予測範囲の絞り込みと統計情報

予測データに対して表示期間をスライダーで指定でき、その範囲内の統計情報が自動で計算されます。

  • 平均値
  • 最大値・最小値
  • 指定期間のグラフ表示
// 範囲指定後に統計を計算する例(React)
const stats = useMemo(() => {
  const filtered = forecastData.filter(
    d => d.date >= rangeStart && d.date <= rangeEnd
  );
  const values = filtered.map(d => d.yhat);
  return {
    mean: values.reduce((a, b) => a + b, 0) / values.length,
    max: Math.max(...values),
    min: Math.min(...values),
  };
}, [forecastData, rangeStart, rangeEnd]);

グラフのダウンロード

表示中のRechartsグラフをそのままPNGで保存できます。html2canvasを使って実装しました。

import html2canvas from "html2canvas";

const handleDownload = async () => {
  const canvas = await html2canvas(chartRef.current);
  const link = document.createElement("a");
  link.download = "salescast_chart.png";
  link.href = canvas.toDataURL();
  link.click();
};

開発でハマったところ

FastAPI × Vercel のCORS設定

フロントとバックが別ドメインになるため、CORSの明示指定が必要です。

main.py
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://salescast.vercel.app"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

開発中は allow_origins=["*"] にしていましたが、本番では必ず絞るようにしました。

RenderのコールドスタートへのUX対応

Renderの無料プランはアイドル時間後の初回リクエストが遅延します。フロント側にローディングスピナーを実装して、ユーザーが離脱しないようにしています。


まとめ

  • FastAPI:Pythonで素早くAPIを立てられる。Prophetとの相性もよい
  • Prophet:時系列予測が手軽にできる。パラメータが少なく扱いやすい
  • Recharts:Reactと組み合わせやすく、インタラクティブなグラフが作りやすい

実際に使ってみて、フィードバックいただけると嬉しいです。

https://salescast.vercel.app

GitHub: @Mecharhythm

Discussion