Skip to content

Add Seibu Bus GTFS support#1530

Merged
TinyKitten merged 3 commits into
devfrom
feature/seibu-bus
May 31, 2026
Merged

Add Seibu Bus GTFS support#1530
TinyKitten merged 3 commits into
devfrom
feature/seibu-bus

Conversation

@TinyKitten

@TinyKitten TinyKitten commented May 31, 2026

Copy link
Copy Markdown
Member

概要

西武バスのGTFSフィードをODPT経由で取り込めるようにしました。既定では従来どおり都営バスのみを使用し、ENABLE_EXPERIMENTAL_BUS_FEATURE=true の場合に西武バスを含む全設定済みGTFSフィードを使用します。

変更の種類

  • バグ修正
  • 新機能
  • データの修正・追加
  • リファクタリング
  • ドキュメント
  • CI/CD
  • その他

変更内容

  • GTFSフィード設定を都営バスと西武バスで扱える形にし、内部IDに toei: / seibu: の名前空間を付与しました。
  • 西武バスGTFS URLのトークンは ODPT_ACCESS_TOKEN から取得するようにしました。
  • ENABLE_EXPERIMENTAL_BUS_FEATURE を追加し、未設定または偽の場合は都営バスのみ、真の場合は全GTFSフィードを使用するようにしました。
  • GTFS側にラインカラーがない場合は、定数化した既定色 #1f63c6 を使用して lines.line_color_c のNOT NULL制約に違反しないようにしました。
  • 西武バスの会社データを追加し、GTFSバス連携と環境変数のドキュメントを更新しました。

テスト

  • cargo fmt --all -- --check が通ること
  • cargo clippy -- -D warnings が通ること
  • cargo testSQLX_OFFLINE=true)が通ること

追加で実行した確認:

  • cargo fmt
  • cargo run -p data_validator
  • cargo check -p stationapi

関連Issue

なし

スクリーンショット(任意)

なし

Summary by CodeRabbit

リリースノート

  • New Features

    • 実験的なバス機能フラグを追加し、Seibu Busなどの追加バスフィード対応を可能にしました。
    • 複数のGTFSバスフィード並列取得に対応しました。
  • Documentation

    • 環境変数、デプロイ手順、GTFS統合に関するドキュメントを更新しました。
  • Chores

    • 環境変数設定ファイルの管理方法を整理しました。
    • Docker Composeの設定を更新しました。

@github-actions github-actions Bot added feature 要望対応や課題解決 deploy-dev and removed feature 要望対応や課題解決 labels May 31, 2026
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f2fa3be-8cf0-4d95-8a46-d16f37c675b4

📥 Commits

Reviewing files that changed from the base of the PR and between 956cd0e and be46f17.

📒 Files selected for processing (1)
  • stationapi/src/import.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • stationapi/src/import.rs

📝 Walkthrough

Walkthrough

このPRは、GTFS バス取り込みシステムを東京交通局(Toei)のみから西武バス(Seibu)を含む複数フィード対応へ拡張します。新しい環境変数 ENABLE_EXPERIMENTAL_BUS_FEATUREODPT_ACCESS_TOKEN を導入し、import.rs を改修してフィード別ダウンロードの並列化、DB トランザクション内でのフィード単位処理、ID のスコープ化、会社コード判定、統合ロジックの正規化を実装しました。

Changes

複数フィード対応の GTFS バス取り込みシステム

Layer / File(s) Summary
環境変数・設定・ドキュメント整備
.env, compose.yml, AGENTS.md, docs/architecture.md
ENABLE_EXPERIMENTAL_BUS_FEATUREODPT_ACCESS_TOKEN を追加。compose.yml.env.local を読み込み、運用手順と実験フラグの挙動をドキュメント化。
フィード定義と取得基盤
stationapi/src/import.rs
GtfsFeed とフィード一覧、取得 URL 組立(ODPT トークン付与)と download_gtfs(feed) を導入し、フィード別 ZIP 取得/展開を実装。
マルチフィード取り込みの並列化とトランザクション管理
stationapi/src/import.rs
import_gtfs で有効フィード群を決定し、各フィードのダウンロード/展開を spawn_blocking で並列実行。DB トランザクション内でフィード毎の処理を順次実行。
フィード別 ID スコープとテーブル取り込み
stationapi/src/import.rs
agencies/routes/stops/calendar/calendar_dates/shapes/trips/stop_times/feed_info の取り込みを feed 引数を受け取る形に変更し、ID を feed_id:... でスコープ化。翻訳参照キーは元の stop_id を使用。
環境フラグ判定と会社コード解決
stationapi/src/import.rs
共通 env_flag_enabled を整備し、company_cd_for_gtfs_route(route_id) を追加して route_id プレフィックスから会社コードを判定。
路線統合と表示正規化
stationapi/src/import.rs
integrate_gtfs_routes_to_lines で未対応プレフィックスのルートをスキップし、路線色の # 付与とデフォルト色適用を正規化。
テスト・ユニットテスト追加
stationapi/src/import.rs
company_cd_for_gtfs_routegtfs_feeds_for_experimental_enabled のユニットテストを追加。

Sequence Diagram

sequenceDiagram
  participant Env as ".env / .env.local"
  participant Compose as "docker-compose"
  participant API as "API Container"
  participant Importer as "import_gtfs"
  participant Downloader as "download_gtfs"
  participant ODPT as "ODPT API"
  participant DB as "Database"

  Env->>Compose: env 読み込み (ENABLE_EXPERIMENTAL_BUS_FEATURE / ODPT_ACCESS_TOKEN)
  Compose->>API: 環境変数注入
  API->>Importer: import_gtfs 実行
  Importer->>Downloader: spawn_blocking で各 feed の download_gtfs
  Downloader->>ODPT: GET (token を含む場合あり)
  Downloader->>Importer: ZIP 展開完了
  Importer->>DB: トランザクション内でフィード毎に import_* を実行・INSERT
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested labels

feature

Poem

🐰 ぽんぽん跳ねて知らせるよ、
フィードが増えて道が広がるよ。
フラグを立てれば Seibu も来る、
スコープ付き ID で整列する、
さあ一緒に走ろう、新しいバス路線へ!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PRのタイトル「Add Seibu Bus GTFS support」は、このPRの主な変更内容(西武バスのGTFS対応を追加)を明確かつ簡潔に表現しており、チェンジセット全体の中心的な変更を正しく反映しています。
Description check ✅ Passed PR説明はテンプレート構造にほぼ従い、概要・変更の種類・変更内容・テスト・関連Issue・スクリーンショットの各セクションが含まれており、変更内容が十分に記述されています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/seibu-bus

Comment @coderabbitai help to get the list of available commands and usage tips.

@TinyKitten TinyKitten self-assigned this May 31, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
stationapi/src/import.rs (1)

357-362: ⚡ Quick win

spawn_blocking が直列実行になっており、複数フィード時の起動時間を不必要に伸ばしています。

for 内で即 await しているため、実際には並列ダウンロードになっていません。ハンドルを溜めて最後に join してください。

差分案
-    for feed in enabled_feeds.iter().copied() {
-        tokio::task::spawn_blocking(move || download_gtfs(feed))
-            .await
-            .map_err(|e| format!("Failed to spawn blocking task: {}", e))?
-            .map_err(|e| -> Box<dyn std::error::Error> { e })?;
-    }
+    let mut handles = Vec::with_capacity(enabled_feeds.len());
+    for feed in enabled_feeds.iter().copied() {
+        handles.push(tokio::task::spawn_blocking(move || download_gtfs(feed)));
+    }
+    for handle in handles {
+        handle
+            .await
+            .map_err(|e| format!("Failed to spawn blocking task: {}", e))?
+            .map_err(|e| -> Box<dyn std::error::Error> { e })?;
+    }

Based on learnings: "Prioritize quality and performance over implementation speed. Always favor code quality and runtime performance over velocity, considering algorithmic complexity and opportunities to replace O(n×m) linear scans with O(n+m) indexed lookups."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@stationapi/src/import.rs` around lines 357 - 362, The loop currently awaits
each tokio::task::spawn_blocking immediately, causing serial execution; instead,
spawn all tasks first and collect their JoinHandle<Result<_, Box<dyn Error>>>
(the handles created by tokio::task::spawn_blocking calling download_gtfs), then
await them all later (e.g., via futures::future::join_all or iterating the
handles) and map JoinError and the inner Result into the same error handling you
already do. Locate the loop using enabled_feeds.iter().copied(), the
spawn_blocking(...) call and the download_gtfs function; change it to push each
spawn_blocking handle into a Vec, then after the loop await all handles and
propagate/map both spawn join errors and download_gtfs errors exactly as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@stationapi/src/import.rs`:
- Around line 1612-1618: The current company_cd_for_gtfs_route(route_id: &str)
silently defaults unknown prefixes to Toei (119); change it to return
Option<i32> (or Result<i32, Error>) instead of a hardcoded i32 so
unknown/unsupported prefixes are reported to the caller; update
company_cd_for_gtfs_route to return Some(253) for "seibu:" and None for anything
else (or Err with a clear message), and then update its callers (the import path
that maps GTFS routes) to skip or explicitly error when None/Err is returned so
unknown prefixes are not ingested as 119.

---

Nitpick comments:
In `@stationapi/src/import.rs`:
- Around line 357-362: The loop currently awaits each
tokio::task::spawn_blocking immediately, causing serial execution; instead,
spawn all tasks first and collect their JoinHandle<Result<_, Box<dyn Error>>>
(the handles created by tokio::task::spawn_blocking calling download_gtfs), then
await them all later (e.g., via futures::future::join_all or iterating the
handles) and map JoinError and the inner Result into the same error handling you
already do. Locate the loop using enabled_feeds.iter().copied(), the
spawn_blocking(...) call and the download_gtfs function; change it to push each
spawn_blocking handle into a Vec, then after the loop await all handles and
propagate/map both spawn join errors and download_gtfs errors exactly as before.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2c63251a-2419-4668-8f64-c3d4105faf7d

📥 Commits

Reviewing files that changed from the base of the PR and between 8933f1a and 956cd0e.

⛔ Files ignored due to path filters (1)
  • data/1!companies.csv is excluded by !**/*.csv
📒 Files selected for processing (5)
  • .env
  • AGENTS.md
  • compose.yml
  • docs/architecture.md
  • stationapi/src/import.rs

Comment thread stationapi/src/import.rs Outdated
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • stationapi/src/import.rs

Commit: be46f17e9cb92fe37cedf5fdf1e6fe6fd4505ec9

The changes have been pushed to the feature/seibu-bus branch.

Time taken: 4m 10s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@github-actions github-actions Bot added the feature 要望対応や課題解決 label May 31, 2026
@TinyKitten TinyKitten merged commit 22ba8d8 into dev May 31, 2026
13 checks passed
@TinyKitten TinyKitten deleted the feature/seibu-bus branch May 31, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deploy-dev feature 要望対応や課題解決

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant