# アーキテクチャ設計書

## 概要

本ドキュメントは、Shopwareプラットフォーム（バージョン6.7系）のアーキテクチャ設計を記述したものです。ShopwareはSymfony 7.4をベースとしたモダンなPHP ECプラットフォームであり、モジュラーバンドル構成、Data Abstraction Layer (DAL)、マルチチャネル（SalesChannel）アーキテクチャを採用しています。

## システム全体構成

### アーキテクチャ概要図

アーキテクチャ全体構成の視覚的な表現については、[アーキテクチャ構成図.md](./アーキテクチャ構成図.md)を参照してください。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| MariaDB/MySQL | Doctrine DBAL | プライマリデータストア（商品、注文、顧客等） |
| OpenSearch/Elasticsearch | OpenSearch PHP Client | 商品検索、フルテキスト検索、集計 |
| Valkey/Redis | Predis/Redis Client | キャッシュ、セッション管理 |
| SMTP (Mailpit等) | Symfony Mailer | メール送信（注文確認、パスワードリセット等） |
| 外部決済プロバイダー | REST API / Webhook | 決済処理 |
| Shopware Store | REST API | プラグイン・アプリマーケット連携 |
| 外部サービス (Apps) | Webhook / REST API | サードパーティアプリ連携 |

## レイヤー構成

### アーキテクチャスタイル

Shopwareは**モジュラーモノリス**アーキテクチャを採用しており、以下の特徴を持ちます：

- **バンドルベースのモジュール化**: Symfonyバンドルシステムを活用した疎結合なモジュール構成
- **ドメイン駆動設計 (DDD) の部分的適用**: エンティティ定義、リポジトリパターン、イベント駆動
- **ヘキサゴナルアーキテクチャの要素**: アダプター層（Database、Cache、Filesystem等）による外部依存の抽象化
- **レイヤードアーキテクチャ**: Presentation、Application、Domain、Infrastructure の明確な分離

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Presentation | HTTPリクエスト処理、レスポンス生成、テンプレートレンダリング | Controller、Storefront、Administration |
| Application (Framework) | ビジネスロジックの調整、ユースケース実行、API提供 | Service、MessageHandler、Flow |
| Domain | ビジネスルール、エンティティ定義、ドメインロジック | EntityDefinition、Entity、Rule |
| Infrastructure | 外部システム連携、永続化、キャッシュ、メッセージング | DAL、Adapter、Repository |

### レイヤー間の依存関係ルール

- **依存の方向性**: 上位レイヤーは下位レイヤーに依存可能（Presentation → Application → Domain → Infrastructure）
- **許可される参照**:
  - Controller → Service → EntityRepository → EntityDefinition
  - 横断的関心事（Log、Event、Cache）は全レイヤーからアクセス可能
- **禁止される参照**:
  - Infrastructure層からPresentationへの直接参照
  - EntityからControllerへの依存
  - Core/FrameworkからStorefront/Administrationへの直接依存

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| Framework | 基盤機能、DAL、API、プラグイン管理 | Core/Framework |
| Checkout | 注文処理、カート、決済、配送 | Core/Checkout |
| Content | 商品、カテゴリ、CMS、メディア管理 | Core/Content |
| System | システム設定、SalesChannel、言語、通貨 | Core/System |
| Service | 外部サービス連携、ライフサイクル管理 | Core/Service |
| Administration | 管理画面（Vue.js SPA） | Administration |
| Storefront | 顧客向けフロントエンド（Twig + JS） | Storefront |
| Elasticsearch | 検索エンジン連携 | Elasticsearch |

### パッケージ構造

```
src/
├── Administration/           # 管理画面バンドル
│   ├── Controller/          # 管理API用コントローラー
│   ├── Resources/app/       # Vue.js管理画面アプリ
│   └── Snippet/             # 管理画面スニペット
├── Core/                     # コアドメインロジック
│   ├── Checkout/            # チェックアウトドメイン
│   │   ├── Cart/            # カート管理
│   │   ├── Customer/        # 顧客管理
│   │   ├── Document/        # ドキュメント生成
│   │   ├── Order/           # 注文管理
│   │   ├── Payment/         # 決済処理
│   │   ├── Promotion/       # プロモーション
│   │   └── Shipping/        # 配送管理
│   ├── Content/             # コンテンツドメイン
│   │   ├── Category/        # カテゴリ
│   │   ├── Cms/             # CMSページ
│   │   ├── Flow/            # ワークフロー自動化
│   │   ├── Media/           # メディア管理
│   │   ├── Product/         # 商品管理
│   │   └── Seo/             # SEO管理
│   ├── Framework/           # フレームワーク基盤
│   │   ├── Adapter/         # 外部連携アダプター
│   │   ├── Api/             # API基盤
│   │   ├── App/             # アプリシステム
│   │   ├── DataAbstractionLayer/  # DAL
│   │   ├── MessageQueue/    # 非同期メッセージング
│   │   ├── Plugin/          # プラグインシステム
│   │   ├── Routing/         # ルーティング
│   │   └── Webhook/         # Webhook管理
│   ├── System/              # システムドメイン
│   │   ├── SalesChannel/    # 販売チャネル
│   │   ├── User/            # ユーザー管理
│   │   └── SystemConfig/    # システム設定
│   └── Service/             # サービス連携
├── Elasticsearch/            # Elasticsearch連携
│   ├── Product/             # 商品検索
│   └── Framework/           # ES基盤
└── Storefront/              # 顧客向けストアフロント
    ├── Controller/          # ストアフロントコントローラー
    ├── Page/                # ページローダー
    ├── Pagelet/             # ページレット（部分ページ）
    ├── Theme/               # テーマシステム
    └── Resources/           # テンプレート、アセット
```

### コンポーネント依存関係

主要コンポーネント間の依存関係は以下のとおりです：

1. **Storefront** → **Core (Framework, Checkout, Content, System)**: ストアフロント機能はコアモジュールに依存
2. **Administration** → **Core (Framework)**: 管理画面はFrameworkのAPI機能に依存
3. **Elasticsearch** → **Core (Framework, Content)**: 検索機能はDALとProductに依存
4. **Core/Checkout** → **Core/Framework, Core/Content, Core/System**: チェックアウトは他コアモジュールに依存
5. **Plugin/App** → **Core/Framework**: 拡張機能はFrameworkの拡張ポイントを利用

## ミドルウェア構成

### データベース

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| RDB | MariaDB / MySQL | MariaDB latest / MySQL 8.0+ | 商品、注文、顧客等の永続化 |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| Valkey/Redis | Valkey Alpine | HTTPキャッシュ、オブジェクトキャッシュ、セッション | 設定依存 |
| Symfony Cache | 7.4 | アプリケーションキャッシュ（ファイル/Redis） | 設定依存 |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Symfony Messenger | 7.4 | 非同期タスク処理（メール送信、インデクシング、スケジュールタスク） |
| Doctrine Transport | - | メッセージの永続化（デフォルト） |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| OpenSearch | 2.x | 商品検索、フルテキスト検索、集計分析 |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Mailpit | latest | 開発環境メール確認（SMTP） |
| Adminer | latest | 開発環境DB管理 |
| Caddy | - | 開発環境Webサーバー |
| Vite | 8.x | フロントエンドビルド（Administration） |

## データフロー

### リクエスト処理の流れ

**Storefront (顧客向け) リクエスト:**

1. HTTPリクエストがSymfony Kernelに到達
2. `RouteScopeListener`でルートスコープ（storefront/api/store-api）を判定
3. `SalesChannelRequestContextResolver`でSalesChannelContextを解決
4. StorefrontControllerでPageLoader経由でデータ取得
5. Twigテンプレートでレンダリング
6. HTTPレスポンス返却

**Admin API リクエスト:**

1. HTTPリクエストがSymfony Kernelに到達
2. `ApiRequestContextResolver`でContextを解決
3. OAuth2認証（Bearer Token）の検証
4. ApiControllerでDAL経由でCRUD操作
5. JSONレスポンス返却

**Store API リクエスト:**

1. HTTPリクエストがSymfony Kernelに到達
2. `sw-access-key`ヘッダーでSalesChannel認証
3. `sw-context-token`でセッション管理
4. Store APIエンドポイントでビジネスロジック実行
5. StructuredJSONレスポンス返却

### 非同期処理の流れ

1. ビジネスロジック内でメッセージ（AsyncMessageInterface実装）を生成
2. Symfony Messenger経由でTransport（sync/async）に送信
3. メッセージワーカーがキューからメッセージを取得
4. MessageHandlerがメッセージを処理
5. 完了/失敗のログ記録

**主な非同期タスク:**
- メール送信
- 検索インデックス更新
- メディアサムネイル生成
- スケジュールタスク実行

### データ永続化の流れ

1. EntityRepository経由でCRUD操作リクエスト
2. VersionManagerでバージョニング処理（対応エンティティのみ）
3. WriteContextで書き込みコンテキスト作成
4. DAL Write/Read操作実行
5. EntityWrittenContainerEventでイベント発火
6. キャッシュ無効化処理

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| OAuth2 (Bearer Token) | Core/Framework/Api/OAuth | Admin API、Integration API |
| SalesChannel Access Key | Core/System/SalesChannel | Store API |
| Context Token | SalesChannelContext | 顧客セッション |
| ACL (Access Control List) | Core/Framework/Api/Acl | Admin API権限管理 |
| SSO | Core/Framework/Sso | シングルサインオン |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| アプリケーションログ | Monolog | var/log/{env}.log |
| 監査ログ | Flow + Event | Database (flow_sequence) |
| アクセスログ | Webサーバー | Webサーバーログ |
| デバッグログ | Symfony Profiler | Profiler Storage |

### エラーハンドリング

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| HTTPエラー (4xx/5xx) | ShopwareHttpException | JSON (API) / HTML (Storefront) |
| DALエラー | DataAbstractionLayerException | 詳細エラーメッセージ付きJSON |
| バリデーションエラー | ConstraintViolationException | フィールド別エラー詳細 |
| 認証エラー | ApiException | 401/403レスポンス |
| 内部エラー | FrameworkException | 500レスポンス + ログ記録 |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| DAL Write操作 | WriteContext | REPEATABLE READ (MySQL default) |
| VersionManager操作 | 明示的トランザクション | REPEATABLE READ |
| MessageHandler | 個別トランザクション | REPEATABLE READ |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| Single Responsibility | EntityDefinition | 1エンティティ = 1定義クラス |
| Open/Closed | Plugin/Extension | EntityExtension経由での拡張 |
| Dependency Inversion | Adapter層 | Interface経由での外部連携 |
| Event-Driven | Framework/Event | EntityWrittenEvent等のイベント駆動 |
| Repository Pattern | EntityRepository | エンティティアクセスの抽象化 |

### コーディング規約

- **PHP**: PHP 8.2+、PSR-12準拠、PHP-CS-Fixer使用
- **TypeScript (Admin)**: ESLint + Prettier
- **SCSS**: Stylelint
- **Twig**: Ludtwig（Storefrontテンプレート）
- **命名規則**:
  - Entity: `{EntityName}Entity`
  - Definition: `{EntityName}Definition`
  - Collection: `{EntityName}Collection`
  - Repository: `{entity_name}.repository`（サービスID）
- **Package属性**: 全公開クラスに`#[Package('xxx')]`属性を付与

## 備考

- 本ドキュメントはShopware 6.7.x系（trunk）を対象としています
- プラグイン・アプリによる拡張は本設計に準拠する必要があります
- フロントエンドアーキテクチャ（Administration Vue.js、Storefront JS）の詳細は別途フロントエンド設計書を参照してください
