このアプリケーションは、AI 関連の情報を自動で収集し、Slack や LINE などの通知サービスを通じてユーザーに提供します。以下に、プロジェクトの設計手順とディレクトリ構成を示します。
- Python: アプリケーションの主要なプログラミング言語
- Docker: コンテナ化による環境構築
- Kubernetes: コンテナのオーケストレーション
- Google Cloud Platform (GCP): クラウドサービスの利用
- Slack API: 通知サービスの一つ
- LINE Messaging API: 通知サービスの一つ
プロジェクトのディレクトリ構造は以下の通りです。
# プロジェクト構造
プロジェクトのディレクトリ構造は以下の通りです。
.
├── README.md # プロジェクトの概要、使い方、インストール方法などを記載したドキュメント
├── build # Dockerイメージを作成するためのファイルが格納されているディレクトリ
│ └── Dockerfile # Dockerコンテナ用の設定ファイル
├── cmd # コマンドラインツールやエントリーポイントに関連するディレクトリ(もしあれば)
├── configs # 設定ファイルが格納されるディレクトリ
│ └── config.py # アプリケーション設定ファイル(データベース設定や環境変数など)
├── deployments # デプロイに関連するファイル(Kubernetes, Dockerなど)
├── docker-compose.yaml # Dockerコンテナを連携させるための設定ファイル
├── docs # ドキュメント関連のファイル(APIドキュメント、設計書など)
├── requirements.txt # プロジェクトの依存関係を記述したファイル
├── scripts # スクリプト(DBマイグレーション、バッチ処理など)
├── src # ソースコード本体
│ ├── application # アプリケーション層(ビジネスロジック)
│ │ ├── services # アプリケーションサービス(ビジネスロジックをサポートする機能)
│ │ │ ├── search_service.py # 検索機能に関するサービス
│ │ │ ├── slack_notification_service.py # Slack通知関連のサービス
│ │ │ └── summarization_service.py # 要約機能関連のサービス
│ │ └── usecase # アプリケーションのユースケースを定義したディレクトリ
│ │ ├── search.py # 検索のユースケース
│ │ ├── slack_notification.py # Slack通知のユースケース
│ │ └── summarization.py # 要約機能のユースケース
│ ├── domain # ドメイン層(ビジネスルール)
│ │ ├── entities # ドメインエンティティ(アプリケーションの中心となるオブジェクト)
│ │ │ └── notification.py # 通知関連のドメインエンティティ
│ │ ├── models # ドメインモデル(データモデル)
│ │ │ └── article.py # 記事のドメインモデル
│ │ ├── repository # リポジトリ層(データ永続化)
│ │ │ └── article_repository.py # 記事データを操作するリポジトリ
│ │ └── services # ドメインサービス(ビジネスロジック)
│ ├── infrastructure # インフラストラクチャ層(外部サービスとの連携)
│ │ ├── external_services # 外部サービスとの連携部分
│ │ │ ├── archive_client.py # アーカイブサービスのクライアント
│ │ │ ├── gemini_client.py # Gemini APIのクライアント
│ │ │ ├── line_notify.py # LINE Notify APIのクライアント
│ │ │ ├── qiita_client.py # Qiita APIのクライアント
│ │ │ └── slack_notify.py # Slack Notify APIのクライアント
│ │ └── repositories # リポジトリ実装(データの永続化実装)
│ │ └── search_repository.py # 検索機能のリポジトリ実装
│ ├── interfaces # インターフェース層(外部とのやり取り)
│ │ ├── api # APIのハンドラー(エンドポイント処理)
│ │ │ └── v1 # バージョン1のAPIハンドラー
│ │ │ ├── article_handler.py # 記事関連のAPIハンドラー
│ │ │ ├── line_notify.py # LINE通知関連のAPIハンドラー
│ │ │ └── slack_notify.py # Slack通知関連のAPIハンドラー
│ │ └── handlers # その他のハンドラー(API以外も含む)
│ │ └── api.py # API全体のエントリーポイント
│ └── main.py # アプリケーションのエントリーポイント(FastAPIの起動など)
└── tests # テストコード
このプロジェクトは、アプリケーションをモジュール化し、層ごとに責任を分割する設計を採用しています。以下はディレクトリ構造の概要です。
README.md: プロジェクトの概要やセットアップ手順などの情報が記載されています。build/: Docker ファイルなど、ビルドに関連する設定ファイルが格納されています。Dockerfile: アプリケーションのコンテナイメージをビルドするためのファイルです。
cmd/: エントリーポイントやコマンドラインの処理を担当するコードが格納されるディレクトリです(未使用の場合もあります)。configs/: 設定ファイルを格納するディレクトリです。アプリケーションの設定値や環境変数が含まれます。config.py: アプリケーションの共通設定が記載されています。
deployments/: デプロイ関連の設定ファイルを格納します。Kubernetes や Docker 関連の設定が含まれます。docker-compose.yaml: 開発環境でのコンテナの構成を記述したファイルです。docs/: ドキュメントを格納するディレクトリです。プロジェクトの詳細や技術的な仕様が含まれます。requirements.txt: Python の依存パッケージを記述したファイルです。scripts/: マイグレーションスクリプトやバッチ処理用のスクリプトが格納されるディレクトリです。
-
application/: アプリケーション層。ユースケースに関連するロジックやサービスが含まれます。services/: ユースケースのサービス実装を格納します。search_service.py: 検索に関連するサービス。slack_notification_service.py: Slack 通知に関するサービス。summarization_service.py: 記事の要約処理に関するサービス。
usecase/: 各ユースケースを表現するクラスや関数が含まれます。search.py: 検索ユースケース。slack_notification.py: Slack 通知ユースケース。summarization.py: 記事要約ユースケース。
-
domain/: ドメイン層。ビジネスロジックの核となるエンティティやサービスを定義します。entities/: ドメインエンティティ(ビジネスの中心となるオブジェクト)。notification.py: 通知に関するエンティティ。
models/: データモデルや DTO(Data Transfer Object)。article.py: 記事に関するデータモデル。
repository/: 永続化層のリポジトリインターフェース。article_repository.py: 記事リポジトリのインターフェース。
services/: ドメインサービス(ビジネスロジックの一部)。
-
infrastructure/: インフラストラクチャ層。外部システムとのやりとりを管理します。external_services/: 外部 API やサービスのクライアント。archive_client.py: アーカイブサービスのクライアント。gemini_client.py: Gemini API のクライアント。line_notify.py: LINE 通知のクライアント。qiita_client.py: Qiita API のクライアント。slack_notify.py: Slack 通知のクライアント。
repositories/: リポジトリ実装。データベースやキャッシュとのインターフェースを実装します。search_repository.py: 検索に関連するリポジトリ実装。
-
interfaces/: インターフェース層。外部とのやり取りや HTTP リクエストを処理します。api/: API 関連のコード。v1/: API のバージョン 1 に関連するコード。article_handler.py: 記事関連の HTTP リクエストを処理するハンドラ。line_notify.py: LINE 通知関連の HTTP リクエストを処理するハンドラ。slack_notify.py: Slack 通知関連の HTTP リクエストを処理するハンドラ。
handlers/: 共通のハンドラ。api.py: API 全体の設定やルーティングを処理します。
-
main.py: アプリケーションのエントリーポイント。サーバーの起動や初期設定を行います。
- プロジェクト内で使用されるユニットテストや統合テストが含まれます。各ディレクトリ(
domain,application,infrastructure,interfaces)ごとにテストコードが格納されます。
-
core/application/services: ビジネスロジックを実装します。例えば、検索サービス(search_service.py)や要約サービス(summarization_service.py)などです。
-
core/domain/entities: ドメインエンティティを定義します。例えば、記事(article.py)などです。
-
core/interfaces: 外部とのインターフェースを定義します。
-
api_clients: 外部 API との通信を担当するクライアントを配置します。
-
handlers: 外部からのリクエストを処理するハンドラーを配置します。
-
infrastructure/external_services: 外部サービスとの通信を担当するクライアントを配置します。
- archive_client.py: アーカイブサービスとの通信を担当します。
- gemini_client.py: Google Gemini との通信を担当します。
- line_notify.py: LINE 通知を担当します。
- qiita_client.py: Qiita との通信を担当します。
- slack_notify.py: Slack 通知を担当します。
- infrastructure/repositories: データベースとのやり取りを担当するリポジトリを配置します。
- search_repository.py: 検索に関連するデータの取得や保存を担当します。
このプロジェクトは、クリーンアーキテクチャ(Clean Architecture)とドメイン駆動設計(DDD)を基盤にした設計が採用されています。これにより、システムの可読性、拡張性、保守性を高め、ビジネスロジックの中心となる「ドメイン」に焦点を当てています。
クリーンアーキテクチャの主要な特徴は、アプリケーションの構造を層に分け、それぞれの層が特定の責務を担うことです。具体的には、以下のように構成されています。
- 依存関係の逆転:上位層が下位層に依存せず、逆に下位層が上位層に依存することがないように設計されています。ビジネスロジックは外部の技術に依存せず、常にアプリケーションの中心に位置します。
- 層ごとの責任分担:
- ドメイン層(ビジネスロジック):
domainディレクトリに該当。ビジネスルール、ドメインモデル(エンティティ、集約)、ドメインサービスなどを格納し、システムの中核として位置します。 - アプリケーション層(ユースケース):
applicationディレクトリに該当。ユースケースはビジネスロジックを利用してユーザーや他システムと対話します。アプリケーションサービスはビジネスロジックを実行し、ドメイン層のエンティティとやりとりします。 - インフラ層(外部サービス、データ永続化):
infrastructureディレクトリに該当。データベースや外部サービスとの接続・通信、リポジトリ実装などを担当します。インフラ層はアプリケーション層に依存し、逆はありません。 - インターフェース層(API や外部との接続):
interfacesディレクトリに該当。外部からのリクエストを処理するハンドラーや API エンドポイントを実装します。インターフェース層はアプリケーション層とやりとりし、リクエストの受け取りやレスポンスの返却を行います。
- ドメイン層(ビジネスロジック):
ドメイン駆動設計(DDD)は、システムの複雑さをドメインモデルで管理し、ビジネスロジックを中心に構築するアプローチです。このプロジェクトでは、以下の DDD の概念を採用しています:
- ドメインモデル:
domain/modelsディレクトリに該当。ビジネスの中心となるエンティティ(例:Article、Notification)を定義し、システム内のビジネスロジックや状態を管理します。 - エンティティ(Entity):
domain/entitiesディレクトリに該当。ドメインの中で一意に識別され、ライフサイクルを通じて状態が変化するオブジェクト(例えば、記事や通知)を定義します。 - 集約(Aggregate):複数のエンティティが関連し、単一の一貫した状態を持つオブジェクトを扱います。例えば、
ArticleSummaryなどが集約の役割を果たします。 - 値オブジェクト(Value Object):不変で同一性を持たないオブジェクトです。例えば、
ArticleIdやSummaryなど、エンティティの一部として扱われるオブジェクトを定義します。 - リポジトリ(Repository):ドメイン層からデータアクセスを切り離し、永続化に関するロジックを管理します。
domain/repositoryにリポジトリインターフェースが定義され、infrastructure/repositoriesにリポジトリ実装が格納されます。 - ドメインサービス(Domain Service):ドメインロジックの一部として、複数のエンティティにまたがる処理を行います。例えば、
ArticleServiceやNotificationServiceがこれに該当します。
この設計では、DDD の概念をクリーンアーキテクチャの各層に自然に統合しています。ドメイン層において、ビジネスロジックやドメインオブジェクト(エンティティ、集約など)を中心に設計し、他の層(アプリケーション層、インフラ層、インターフェース層)はドメインロジックを外部環境に適応させる役割を担っています。これにより、ビジネスの要求に応じたシステムの柔軟性が保たれ、技術的な変更や依存関係の変更にも強いアーキテクチャとなります。
マイクロサービスとはビジネスドメインに基づいて分割された、独立してデプロイ可能なサービス。
-
依存関係のインストール
プロジェクトのルートディレクトリで以下のコマンドを実行し、必要なパッケージをインストールします。