# ビルド時間スケーリング計画 (Phase 3-4)

Parky 公開ポータルは Astro 5 の static 出力で運用している。
Phase 2 までは東京中心 (数百ハブ) だったが、全国展開 (Phase 3-1) で
ページ数が数万 〜 10 万規模に到達する見込みのため、
ビルド時間が問題になる手前で選択肢を整理しておく。

## 現在の状況 (2026-04-15)

- 出力: `astro build` → Vercel static (adapter-vercel)
- 主要な動的ルート:
  - `/p/[pref]/[city]/[spot]/` (駅ハブ)
  - `/p/[pref]/[city]/[spot]/[filter]/` (属性フィルタ 5 種)
  - `/spot/[id]/` (駐車場詳細)
  - `/scene/[sceneSlug]/` (4 シーン)
  - `/media/[slug]/` (MDX)
- 主要なビルド時 DB アクセス:
  - `fetchPublishableStationHubs` → 1 回
  - `fetchParkingListForStationHub(stationId)` → 駅ハブ数 × 1 回
  - `fetchReviewIndexByLot` → 1 回 (全 approved レビューを Map に)
  - `fetchAllParkingLotIds` → 1 回 (pagination)
- Phase 2-1 リファクタで上記は全てモジュール単位 Promise キャッシュで重複排除済み

## 計測トリガー

まず計測から始める。以下のタイミングで build 時間を記録:

- 現在 (東京のみ) の build 時間
- kanagawa 解禁後
- osaka 解禁後
- 初の 4 都市同時解禁時

`astro build` 末尾の `build 7 page(s) built in 2.07s` を GitHub Actions の
ログから追うだけで十分。閾値は下記:

- **5 分未満**: 何もしない (ISR 不要、Vercel 無料枠)
- **5〜15 分**: 分割ビルド検討
- **15 分超**: ISR / on-demand revalidation に移行

## 最適化オプション

### Option A: 地域分割ビルド (推奨の第一歩)

`PUBLIC_PUBLISHED_PREFECTURES` を 複数の workflow に分けて回す。
例:
- `deploy-public-prod-kanto.yml` → tokyo,kanagawa,saitama,chiba
- `deploy-public-prod-kansai.yml` → osaka,kyoto,hyogo,nara
- etc.

それぞれ別の Vercel プロジェクト (サブディレクトリビルド) or
同一プロジェクトに対して rsync 差分反映。

- 利点: 既存コード無変更。env だけで制御できる
- 欠点: sitemap をマージする手間、Vercel 側で分割デプロイが面倒
- 実装: Phase 3-1 の仕組みを流用、新 workflow を追加するだけ

### Option B: Vercel ISR (on-demand revalidation)

`output: 'hybrid'` に切替、動的ルートのみ ISR 化。
Supabase 側の更新 webhook から `revalidatePath()` を呼び出して
該当ページだけ再生成する。

- 利点: ビルド時間が劇的に短縮 (初回だけ build、以降は差分)
- 欠点: 複雑度増加、Vercel Pro プラン相当のリソース要
- 前提: adapter を `vercel` のまま使えるが、static export の恩恵を
  一部手放す (キャッシュヒット率で相殺)

### Option C: 差分ビルド (incremental)

Astro 自体は incremental build をサポートしない。
代替: `.vercel/output/static/p/{pref}/` 単位で前回成果物を保持し、
対象地域のみ再ビルド + rsync 差分アップロード。

- 利点: Option B より単純
- 欠点: sitemap / hreflang の整合性管理が手作業
- 使い所: Option A で破綻してから検討

### Option D: DB 側の集計化

現状は各ハブのページ body で `fetchParkingListForStationHub` を呼んでいる。
このクエリが N 回走ることが支配的になったら、
ハブ単位の JSON 集計カラム (`hub_content` JSONB) を MV / cron で
1 度だけ生成しておき、build 時はそれを SELECT するだけにする。

- 利点: ネットワーク往復を 1 本に圧縮
- 欠点: MV 管理とスキーマ複雑化
- 前提: Phase 3-1 の in-memory cache で十分か確認した上で検討

## 推奨プラン

1. **まず計測**: GitHub Actions ログで build 時間を記録
2. 5 分超えたら **Option A (地域分割)** を導入
3. Option A で耐えきれなくなったら **Option D (JSON 集計)** を入れる
4. Option D でも 15 分を超えるようになったら **Option B (ISR)** に
   移行検討

コード変更は Phase 3 段階では不要。本ドキュメントは「問題化したとき
すぐ動ける」ための設計メモ。
