通知概要
説明
通知システムコンポーネントは、ウィッシュリスト製品およびグループの売上データ変更に関するリアルタイム通知を管理します。このシステムはLaravelの通知システムを活用して、コンソールデータベース(gb_console)とアナライザーデータベース(gb_analyzer)からデータを処理し、ユーザー定義のしきい値(比率型または金額型)に基づいて重要な変更を特定し、データベース保存とリアルタイムPusherサービスの両方を通じて通知を配信します。このコンポーネントにより、ユーザー定義の基準に基づいて製品および製品グループの売上パフォーマンスの変化を自動的に監視し、エンドユーザーに重要なビジネスメトリクスをタイムリーに認識させることができます。
システム概要図
---
config:
theme: base
layout: dagre
flowchart:
curve: linear
htmlLabels: true
themeVariables:
edgeLabelBackground: "transparent"
---
flowchart TB
%% External services
PusherAPI((Pusher API))
%% Commands
SendNotification[notification:sale-one-month]
%% Database tables grouped by database
subgraph ConsoleDB["Console Database (gb_console)"]
direction TB
NotificationSettings[(notification_settings)]
Notifications[(notifications)]
Groups[(groups)]
GroupMembers[(group_members)]
Users[(users)]
WishlistProducts[(wishlist_products)]
WishlistGroups[(wishlist_groups)]
Subscriptions[(subscriptions)]
end
subgraph AnalyzerDB["<div style='width: 300px'>Analyzer Database (gb_analyzer)</div>"]
direction TB
Products[(products)]
ProductDetails[(product_details)]
end
subgraph Commands["Scheduled Commands"]
SendNotification
end
subgraph JobProcessing["Job Processing"]
SendNotificationJob[SendNotificationJob]
end
SendNotification --- Step1[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
<p style='margin-top: 8px'>Retrieve Settings</p>
</div>
]
Step1 --> NotificationSettings
SendNotification --- Step2[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
<p style='margin-top: 8px'>Dispatch Jobs</p>
</div>
]
Step2 --> SendNotificationJob
SendNotificationJob --- Step3[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3</span>
<p style='margin-top: 8px'>Get Product Data</p>
</div>
]
Step3 --> Products
Step3 --> ProductDetails
SendNotificationJob --- Step4[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4</span>
<p style='margin-top: 8px'>Get Group Members</p>
</div>
]
Step4 --> GroupMembers
SendNotificationJob --- Step5[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5</span>
<p style='margin-top: 8px'>Store Notifications</p>
</div>
]
Step5 --> Notifications
SendNotificationJob --- Step6[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6</span>
<p style='margin-top: 8px'>Real-time Delivery</p>
</div>
]
Step6 --> PusherAPI
PusherAPI --- Step7[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7</span>
<p style='margin-top: 8px'>WebSocket</p>
</div>
]
Step7 --> Users
%% Implicit relationships
NotificationSettings -.-> WishlistProducts
NotificationSettings -.-> WishlistGroups
Groups -.-> Subscriptions
%% Database styles
style ConsoleDB fill:#d9f2d9,stroke:#339933,stroke-width:2px
style AnalyzerDB fill:#d9d9f2,stroke:#6666cc,stroke-width:2px
%% Table styles
classDef consoleTable fill:#e6ffe6,stroke:#339933,stroke-width:1px
classDef analyzerTable fill:#e6e6ff,stroke:#6666cc,stroke-width:1px
%% Apply table styles
class NotificationSettings,Notifications,Groups,GroupMembers,Users,WishlistProducts,WishlistGroups,Subscriptions consoleTable
class Products,ProductDetails analyzerTable
%% Other styles
style PusherAPI fill:#fcd9d9,stroke:#cc6666,stroke-width:2px
style SendNotification fill:#d9f2d9
style Commands fill:#f9f9f9
style JobProcessing fill:#f0e6ff,stroke:#9966cc,stroke-width:1px
style SendNotificationJob fill:#f5e6ff
%% Transparent connection steps
style Step1 fill:transparent,stroke:transparent,stroke-width:1px
style Step2 fill:transparent,stroke:transparent,stroke-width:1px
style Step3 fill:transparent,stroke:transparent,stroke-width:1px
style Step4 fill:transparent,stroke:transparent,stroke-width:1px
style Step5 fill:transparent,stroke:transparent,stroke-width:1px
style Step6 fill:transparent,stroke:transparent,stroke-width:1px
style Step7 fill:transparent,stroke:transparent,stroke-width:1px
詳細なデータフロー依存関係
通知システムコンポーネントは、以下のステップによる順次データフローに従います:
-
設定の取得:
notification:sale-one-monthコマンドはデータベースから通知設定を取得します:notification_settingsテーブルからアクティブな設定をクエリwhereHas('group.activeSubscription')を使用してアクティブなグループサブスクリプションでフィルタリング- チャンク単位で設定を処理(デフォルト:チャンクあたり100レコード)
chunkDataSendNotification()メソッドを持つNotificationSettingRepositoryInterfaceを使用
-
ジョブのディスパッチ: 通知設定の各チャンクに対して:
- 設定コレクションデータを含む
SendNotificationJobをディスパッチ - 信頼性の高いバックグラウンド処理のためにLaravelキュー設定を適用
- 監視とデバッグのためにディスパッチイベントをログに記録
- 設定コレクションデータを含む
-
製品データの取得: ジョブは関連する製品と売上データを取得します:
- 個別製品通知の場合:特定のウィッシュリスト製品と対応するアナライザー製品を取得
- グループ通知の場合:ウィッシュリストグループ内の複数の製品にわたる集計データを取得
- 日付範囲を使用して
product_detailsテーブルから現在および過去の売上データを取得 - リポジトリインターフェースを通じてデータにアクセス:
ProductRepository、ProductDetailRepository、WishlistProductRepository
-
条件の評価: システムは通知設定に基づいてデータを分析します:
- 比率ベースの通知:
calculate_percentage_change()を使用して現在と過去の期間の間のパーセンテージ変化を計算 - 金額ベースの通知:固定しきい値に対して絶対的な売上値を比較
- 売上計算:売上値決定のための
sales_one_month * priceを使用 - 比較タイプに基づいて通知基準が満たされているかを判断:
- 増加/減少(パーセンテージしきい値を持つ比率タイプの場合)
- 超過/下回る(絶対値しきい値を持つ金額タイプの場合)
- 比率ベースの通知:
-
グループメンバーの取得: 条件が満たされた場合、システムは:
group_idを通じて通知設定に関連付けられたグループメンバーを特定GroupRepositoryを使用してグループメンバー関係を通じてユーザーレコードを取得- ユーザー固有のコンテキストでパーソナライズされた通知データを準備
-
通知の保存: 条件を満たす各通知に対して:
- Laravelの通知システムを使用して
notificationsテーブルに新しいレコードを作成 - 比較値、エンティティ参照、タイムスタンプを含む構造化JSONデータを保存
- 適切なデータフォーマットでデータベース保存のために
SendNotificationクラスを使用 - 監査と既読追跡のための配信ステータスを維持
- Laravelの通知システムを使用して
-
リアルタイム配信: 最後に、システムは通知を配信します:
toPusher()メソッドを使用してPusher WebSocketsを介してリアルタイム更新を送信- Laravel通知イベントリスナーを通じて配信ステータスを追跡
- エラーを処理し、データベースのみの配信へのフォールバックを提供
- 監視のために成功および失敗した通知試行をログに記録
データベーススキーマ
コンソールデータベーステーブル (gb_console)
erDiagram
notification_settings {
bigint id PK
string notifiable_type "ポリモーフィックタイプ(ジョブ処理でのエンティティタイプ識別に使用)"
bigint notifiable_id "エンティティを参照するポリモーフィックID(ジョブ処理でのエンティティルックアップに使用)"
bigint group_id FK "groupsテーブルへの外部キー(グループメンバー通知とサブスクリプションフィルタリングに使用)"
string type "通知タイプ:ratio、amount(処理ロジック選択に使用)"
string frequency "通知頻度:previous_day、one_week_ago(日付範囲計算に使用)"
string comparison_type "比較タイプ:increase、decrease、exceed、fall_below(しきい値評価に使用)"
decimal comparison_value "比較のためのしきい値(通知条件チェックに使用)"
timestamp created_at
timestamp updated_at
}
notifications {
uuid id PK
string type "通知クラス名(通知タイプ識別に使用)"
string notifiable_type "ポリモーフィックタイプ(Pusher配信でのユーザー識別に使用)"
bigint notifiable_id "ユーザーを参照するポリモーフィックID(通知ターゲティングに使用)"
text data "設定と比較情報を含むJSON通知データ(Pusherペイロードに使用)"
timestamp read_at "通知が読まれた時間(既読ステータス追跡に使用)"
timestamp created_at
timestamp updated_at
}
groups {
bigint id PK
string name "グループ名(通知コンテキストに使用)"
timestamp created_at
timestamp updated_at
}
group_members {
bigint id PK
bigint group_id FK "groupsテーブルへの外部キー(通知配信でのユーザールックアップに使用)"
bigint user_id FK "usersテーブルへの外部キー(通知ターゲティングに使用)"
timestamp created_at
timestamp updated_at
}
users {
bigint id PK
string name "ユーザー名(通知パーソナライゼーションに使用)"
string email "ユーザーメール(通知配信に使用)"
timestamp created_at
timestamp updated_at
}
subscriptions {
bigint id PK
bigint group_id FK "groupsテーブルへの外部キー(アクティブサブスクリプションフィルタリングに使用)"
string status "サブスクリプションステータス(chunkDataSendNotificationでアクティブ用にフィルタリング)"
timestamp created_at
timestamp updated_at
}
wishlist_products {
bigint id PK
bigint wishlist_group_id FK "wishlist_groupsテーブルへの外部キー(グループ関連付けに使用)"
text summary_product "製品入力情報を含むJSONデータ(製品ID抽出に使用)"
timestamp created_at
timestamp updated_at
}
wishlist_groups {
bigint id PK
string name "ウィッシュリストグループ名(通知コンテキストとグループ処理に使用)"
timestamp created_at
timestamp updated_at
}
notification_settings ||--o{ groups : "belongs to"
groups ||--o{ group_members : "has many"
groups ||--o{ subscriptions : "has many"
group_members ||--o{ users : "belongs to"
notifications ||--o{ users : "notifiable"
notification_settings ||--o{ wishlist_products : "notifiable (polymorphic)"
notification_settings ||--o{ wishlist_groups : "notifiable (polymorphic)"
wishlist_products ||--o{ wishlist_groups : "belongs to"
アナライザーデータベーステーブル (gb_analyzer)
erDiagram
products {
bigint id PK
integer mall_id "モール識別子(製品フィルタリングとマッチングに使用)"
string mall_product_id "モールからの製品ID(入力による製品ルックアップに使用)"
string unique_key "一意の識別子(製品重複排除に使用)"
timestamp created_at
timestamp updated_at
}
product_details {
bigint id PK
bigint product_id FK "productsテーブルへの外部キー(売上データ関連付けに使用)"
decimal price "製品価格(売上値計算に使用:sales_one_month * price)"
integer sales_one_month "1ヶ月間の売上数(売上値計算に使用)"
date metrics_date "メトリクスの日付(過去比較での日付範囲フィルタリングに使用)"
timestamp created_at
timestamp updated_at
timestamp crawl_created_at "データがクロールされた時間(最新データ選択に使用)"
}
products ||--o{ product_details : "has many"
通知コマンドロジックフィールド
通知設定の取得:
コマンドレベル(notification:sale-one-month):
notification_settings.id- チャンク処理のための主キーnotification_settings.group_id-whereHas('group.activeSubscription')によるアクティブサブスクリプションフィルタリングに使用
ジョブレベル(SendNotificationJob):
notification_settings.notifiable_type- エンティティがWishlistProductかWishlistGroupかを判断するために使用notification_settings.notifiable_id- エンティティルックアップ(getEntity()メソッド)に使用notification_settings.type- 処理ロジックの選択(比率vs金額)に使用notification_settings.frequency- 日付範囲計算(getDateRangeForFrequency())に使用notification_settings.comparison_type- しきい値評価ロジックに使用notification_settings.comparison_value- 通知条件チェックに使用notification_settings.group_id- グループメンバーのルックアップと通知配信に使用
製品データ処理:
製品ルックアップ:
products.mall_product_id-getByMallProductId()による製品マッチングに使用products.id- 製品詳細関連付けに使用
売上データ計算:
product_details.product_id- 製品関連付けに使用product_details.sales_one_month- 売上値計算に使用product_details.price- 売上値計算に使用(sales_one_month * price)product_details.metrics_date- 過去比較での日付範囲フィルタリングに使用product_details.crawl_created_at- 最新データ選択に使用
グループメンバー通知:
グループ処理:
groups.id-findById()によるグループルックアップに使用group_members.group_id- メンバー関連付けに使用group_members.user_id- ユーザールックアップに使用users.id- 通知ターゲティングとPusher配信に使用users.name- 通知パーソナライゼーションに使用users.email- 通知配信に使用
通知保存と配信:
データベース保存:
notifications.id- 通知識別のための生成されたUUIDnotifications.type- 通知クラス名に設定notifications.notifiable_type- 'App\Models\User'に設定notifications.notifiable_id- ターゲティングのためのユーザーIDに設定notifications.data- 設定と比較データを含むJSONペイロードを格納notifications.read_at- 既読ステータス追跡に使用
エンティティコンテキスト:
wishlist_products.summary_product- 製品入力抽出に使用wishlist_groups.name- 通知コンテキストに使用
売上値計算ロジック
通知システムは売上監視のために以下の計算を使用します:
売上値 = product_details.sales_one_month * product_details.price
比率タイプ通知:
- 現在期間と過去期間の売上値を比較
calculate_percentage_change()を使用してパーセンテージ変化を計算- 増加/減少しきい値に基づいて通知をトリガー
金額タイプ通知:
- 現在の売上値を絶対的なしきい値と比較
- 値が設定された金額を超過または下回った場合に通知をトリガー
日付範囲処理
システムはproduct_details.metrics_dateを以下のために使用します:
- 現在期間フィルタリング(現在の月)
- 過去期間フィルタリング(前月)
- 日付範囲内の最新データ選択
サブスクリプションフィルタリング
アクティブサブスクリプションフィルタリングは以下を通じて実装されています:
whereHas('group.activeSubscription')
これにより、アクティブなサブスクリプションを持つグループのみが通知を受け取ります。
頻度概要
タイムライン
timeline
title 通知システムスケジュール
section 売上通知
毎日<br>(例:00.00) : notification sale-one-month
: 通知設定を処理しアラートをトリガー
期待される結果
これらのコマンドが正常に実行されると、システムは以下を提供します:
- 自動売上監視: ユーザー定義のしきい値に基づいたウィッシュリスト製品およびグループの売上パフォーマンス変化の継続的な監視
- リアルタイム通知配信: データベース保存とPusher WebSocketサービスの両方を通じた即時通知配信によるユーザーへの瞬時の認識
- 設定可能なしきい値管理: 比率ベース(パーセンテージ)と金額ベース(絶対値)の両方の通知基準を柔軟な比較タイプでサポート
- グループベースの通知配布: サブスクリプションベースのフィルタリングを持つグループメンバーシップ関係を通じた関連ユーザーへの効率的な配信
- 永続的な通知履歴: 既読ステータス追跡と構造化JSONデータ保存を備えたすべての通知の完全な監査証跡
- バックグラウンドジョブ処理: システムパフォーマンスをブロックせずに大量の処理を扱うための信頼性の高い非同期通知チャンク処理
- エラー処理とフォールバック: 外部サービスが失敗した場合のデータベースのみの配信へのフォールバックを持つ堅牢なエラー処理
- データ駆動型ビジネスインテリジェンス: 重要な売上変化と市場動向に対する迅速な対応を可能にするタイムリーなアラート
バッチリスト
| 名前 | 説明 |
|---|---|
| 売上通知 | アクティブなサブスクリプションを持つグループの通知設定を処理し、ウィッシュリスト製品およびグループの売上変化を検出するコマンド |