Egypt Tours(エジプトツアー)
Egypt Tours — グローバル・エクスペリエンス・プラットフォーム SEOを最優先した高コンバージョンなツアー・旅行体験を提供し、スピード、信頼性、ローカライズを実現するエンタープライズグレードのエンジニアリングで構築されています。
Egypt Tours — グローバル・エクスペリエンス・プラットフォーム
SEOを最優先した高コンバージョンなツアー・旅行体験を提供し、スピード、信頼性、ローカライズを実現するエンタープライズグレードのエンジニアリングで構築されています。
当リポジトリは、多言語・多通貨対応の観光プラットフォームを支える、プロダクション環境向けのLaravelアプリケーションです。日帰りツアー、パッケージ、クルーズなど、多種多様な旅行商品の膨大な在庫を運用するという実社会の課題に対し、以下を提供することで解決します。
- 低遅延のクエリとファセット検索に最適化された、高速でフィルタリング可能な商品カタログ。
- 日付範囲ごとの価格設定、キャビン/部屋タイプ別のバリエーション、子供向け料金ポリシーをサポートする柔軟な価格設定および予約エンジン。
- グローバルな利用者を対象とした完全なローカライズ(言語およびスラッグ翻訳)と通貨変換機能。
主要な価値提案とマーケティングのハイライト
-
パフォーマンスとスケーラビリティ: プラットフォームはLaravel 12で構築されており、戦略的な非正規化(
product_filtersテーブル)、CurrencyServiceなどにおけるRedisフレンドリーなキャッシング、Viteを活用したフロントエンドバンドリングによりスケールに最適化されています。重い集計処理は書き込み時に事前計算されるため、フィルタリングや一覧表示における極めて高速な読み込みパスを実現しています。 -
UX / UIの卓越性: Tailwind CSS v4とViteの採用により、レスポンシブかつコンポーネント駆動型のUIを提供します。プログレッシブエンハンスメントおよびJSONエンドポイント(例:
/api/tours-list)が実装されており、高速なクライアントサイド体験とオートコンプリートウィジェットをサポートしています。 -
セキュリティと信頼性: Laravelのベストプラクティスに基づいた設計を採用しており、厳格な環境依存の設定、CSRF保護されたフォーム、Form Requestによる厳密なバリデーション、セキュアなCRUD操作のためのFilament管理画面を備えています。プロジェクトにはPestによるテストコードとPintによるコードフォーマットが含まれており、開発者の衛生管理が徹底されています。
技術アーキテクチャとスタック
-
バックエンド / API
- フレームワーク: Laravel 12 (PHP ^8.2)。
- パターン: MVC + サービス層。主要なサービスとして
FilterService、PricingService、CurrencyServiceを内包(app/Servicesを参照)。 - 管理画面: コンテンツ管理および安全な管理UXのためにFilament v5を採用。
- データベース: リレーショナルデータベース(Postgresを推奨)。ファセット検索を高速化するために非正規化された
product_filtersスキーマを内包。
-
フロントエンド
- ツール: Vite, Tailwind CSS v4。
- コンポーネント: 再利用可能なBladeコンポーネントおよび非同期UI(検索/オートコンプリート)のためのJSON優先エンドポイント。
- サードパーティ: カルーセル用にSwiperを採用。
-
DevOpsとインフラストラクチャ
- ローカル開発用スクリプトがcomposer.jsonに提供されています(
setup,dev,test)。 - CI: テスト用にPest、フォーマット用にPintを使用。CIパイプラインに統合することで品質ゲートを強制可能です。
- キャッシュ: 通貨リストや計算済みフィルタのためにLaravel Cache(Redisを推奨)を使用。
- コンテナ化: Laravel Sailまたはお好みのPHPランタイムを介してDocker内で動作可能です。
- ローカル開発用スクリプトがcomposer.jsonに提供されています(
アーキテクチャ図
graph LR
A[ユーザーブラウザ] -->|HTTP/HTTPS| B[Laravelフロントエンド (Blade + Vite)]
B --> C[ルート/コントローラー]
C --> D[サービス層]
D -->|書き込み| E[product_filtersテーブル]
D -->|読み込み/書き込み| F[商品 / 価格 / 出発日]
F --> G[Postgres]
D --> H[CurrencyService キャッシュ (Redis)]
I[Filament管理画面] --> F
主要機能と技術的な詳細解説
- 商品フィルター(高速なファセット検索)
- 機能: 国、目的地、タクソノミー、価格帯、期間を横断して効率的なファセットフィルタリングを可能にする、
product_filtersに格納された事前計算済み商品フィルター。 - 課題: 大規模な商品カタログや翻訳データに対してアドホックな結合や重い集計処理を実行すると、ページ読み込みの低速化やクエリの複雑化を招く。
- 技術的解決策: 商品の保存/更新時に
FilterService::rebuildProductFilters()(app/Services/FilterService.phpを参照)が正規化された行を構成し、product_filtersに挿入します。読み込みパスでは交差ロジック(getProductIdsByFilters)を使用してフィルター基準を効率的に結合します。これにより、多対多のルックアップがシンプルなインデックス付きクエリに変換され、DB負荷を軽減します。
- 価格設定と予約(日付範囲、キャビン、子供向けポリシー)
- 機能: 価格バリエーション(人単位、キャビン単位)、出発日、日付範囲のオーバーライドを横断した正確な見積もり計算。
- 課題: 価格ルールは旅行日、キャビンや部屋タイプ、子供割引ポリシーによって異なり、システムは一貫性のある監査可能な見積もりを返す必要がある。
- 技術的解決策:
PricingService::calculateQuote()(app/Services/PricingService.phpを参照)は、出発日固有の価格、キャビンの価格、期間設定された価格行、そして最終的な安全なフォールバックを確認することで、正しい基準単位を特定します。子供向け料金にはchildPolicyRulesを使用して年齢ごとの割引を計算し、通貨換算は単一の真実源としてCurrencyServiceに委譲します。実装では妥当な順序(範囲->フォールバック->作成日時)を使用して、正しい価格行を決定論的に選択します。
- 多言語ルーティングとSEO
- 機能: 翻訳されたスラッグを持つローカライズされたルート、正規URL(canonical URL)、言語対応フィルター。
- 課題: 予約されたスラッグとのルーティングの競合を回避し、下位互換性を維持しつつ、SEOフレンドリーなローカライズコンテンツを提供すること。
- 技術的解決策: ルートはグループ化され、routes/web.php内の
SetLocaleミドルウェアとローカライズされた接頭辞グループによって保護されています。国ファーストおよびネストされた商品ルートは、予約済みスラッグの衝突を回避するために正規表現での除外を使用しています。翻訳はエンティティごとの翻訳テーブルに格納されており、翻訳対応フィルター行にはlanguage_idが含まれているため、UIフィルターには選択されたロケールに関連するスラッグのみが表示されます。