Sales CRM 集約: 目標管理 / Aggregate: Goal Tracking
バウンデッドコンテキスト: Operations / Reporting (オペレーション) — 拡張
→ 知識ベース:
knowledge/07-sales-management/performance-management.md(KPI)
集約ルート (Aggregate Roots)
1. Goal (目標項目)
Goal (集約ルート)
├── name: string (目標名)
├── description: string (説明)
├── entityType: GoalEntityType (deals / activities)
├── aggregationMethod: AggregationMethod (count / sum / average)
├── targetField: string (集計対象フィールド — sum/average 時)
├── filterConditions[] (フィルタ条件)
│ ├── field: string (フィルタ対象フィールド)
│ ├── operator: string (equals / in / gte / lte)
│ └── value: string | string[] (フィルタ値)
├── period: GoalPeriod (monthly / quarterly / yearly)
├── isActive: boolean (有効フラグ)
├── displayOrder: number (表示順)
├── createdBy: → User (作成者)
├── updatedBy: → User (最終更新者)
└── version: number (楽観ロック用)
| プロパティ | 型 | 必須 | 説明 |
|---|---|---|---|
| name | string | ✓ | 目標名 (最大 100 文字) |
| description | string | 目標の説明 (最大 500 文字) | |
| entityType | GoalEntityType | ✓ | deals / activities — 集計対象エンティティ |
| aggregationMethod | AggregationMethod | ✓ | count / sum / average |
| targetField | string | 条件付 | 集計対象フィールド名 (sum/average 時必須: 例 amount, duration) |
| filterConditions | FilterCondition[] | フィルタ条件配列 (任意) | |
| period | GoalPeriod | ✓ | monthly / quarterly / yearly |
| isActive | boolean | 有効フラグ (デフォルト: true) | |
| displayOrder | number | 表示順序 (デフォルト: 0) | |
| createdBy | → User | 作成者 (読取専用) | |
| updatedBy | → User | 最終更新者 (読取専用) | |
| version | number | 楽観ロック用 |
フィルタ条件の例:
// 例: 商談の成約金額を集計
{
entityType: "deals",
aggregationMethod: "sum",
targetField: "amount",
filterConditions: [
{ field: "dealType", operator: "equals", value: "negotiation" },
{ field: "status", operator: "equals", value: "won" }
],
period: "monthly"
}
// 例: 電話活動件数を集計
{
entityType: "activities",
aggregationMethod: "count",
filterConditions: [
{ field: "activityType", operator: "in", value: ["call", "inquiry"] }
],
period: "monthly"
}
不変条件 (Invariants):
nameは空文字不可entityTypeはdeals/activitiesのいずれかaggregationMethodはcount/sum/averageのいずれかaggregationMethodがsum/averageの場合、targetFieldは必須targetFieldは対象エンティティの数値フィールド名のみperiodはmonthly/quarterly/yearlyのいずれかfilterConditions[].fieldは対象エンティティの有効なフィールド名- 楽観ロック: バージョン不整合で 409 Conflict
- admin のみ作成・更新・削除可能
2. GoalValue (目標値)
GoalValue (エンティティ — Goal の子)
├── goal: → Goal (親目標項目)
├── user: → User (対象ユーザー、任意 — 全体目標時は null)
├── group: string (対象グループ、任意)
├── periodStart: Date (期間開始日)
├── periodEnd: Date (期間終了日)
├── targetValue: number (目標値)
└── version: number (楽観ロック用)
| プロパティ | 型 | 必須 | 説明 |
|---|---|---|---|
| goal | → Goal | ✓ | 親目標項目 |
| user | → User | 対象ユーザー (個人目標時) | |
| group | string | 対象グループ (グループ目標時) | |
| periodStart | Date | ✓ | 期間開始日 |
| periodEnd | Date | ✓ | 期間終了日 |
| targetValue | number | ✓ | 目標値 (0 以上) |
| version | number | 楽観ロック用 |
不変条件 (Invariants):
goalは必須periodStart<periodEndtargetValue≥ 0- 同一 goal + user + periodStart の組み合わせはユニーク
- 楽観ロック: バージョン不整合で 409 Conflict
読取専用投影: GoalProgress (目標進捗)
GoalProgress はデータベースに永続化しない、都度計算される読取専用の投影。 Goal の定義に基づき、対象エンティティから実績値を集計する。
interface GoalProgress {
/** 目標項目 */
goal: Goal;
/** 対象期間 */
period: { start: Date; end: Date };
/** 目標値 */
targetValue: number;
/** 実績値 (集計結果) */
actualValue: number;
/** 達成率 (%) = actualValue / targetValue × 100 */
achievementRate: number;
/** 差分 = actualValue - targetValue */
variance: number;
}
計算ロジック:
- Goal.entityType に基づき対象コレクション (deals / activities) を選択
- Goal.filterConditions でフィルタリング
- Goal.aggregationMethod に基づき集計:
count: レコード件数sum: targetField の合計値average: targetField の平均値
- RBAC スコーピング適用 (sales_rep は自分の担当分のみ)
トランザクション境界
| 操作 | 同一トランザクション | 結果整合性 (Eventual) |
|---|---|---|
| Goal 作成 | Goal のみ | — |
| GoalValue 設定 | GoalValue のみ | — |
| GoalProgress 取得 | 読取専用 (集計クエリ) | — |
関連図
┌──────────────────┐
│ Goal │
│ (目標項目定義) │
│ │
│ entityType │
│ aggregation │
│ filterConditions│
│ period │
└────────┬─────────┘
│ 1
┌────┼────┐
│ │
N│ N│
┌───┴──────┐ ┌┴───────────────┐
│GoalValue │ │ GoalProgress │
│(目標値) │ │ (実績 — 読取専用)│
│ │ │ │
│ user │ │ actualValue │
│ target │ │ achievementRate│
│ period │ │ variance │
└──────────┘ └────────────────┘
│
集計元 ────┤
│
┌──────────┴──────────┐
│ │
┌────┴─────┐ ┌────┴─────┐
│ Deal │ │ Activity │
│ (案件) │ │ (活動) │
└──────────┘ └──────────┘
- Goal : GoalValue = 1 : N
- Goal : GoalProgress = 1 : N (読取専用投影、都度計算)