Fab Forward Dev/

DDD ドキュメント

Sales CRM 業務ルール集 / Business Rules & Policies

各ドメインの不変条件・ポリシー・バリデーションルールを集約する。 コード実装時はこのドキュメントのルールを検証ロジックとして反映すること。

対応ドメイン: docs/ddd/pms/05-business-rules.md (PMS 側の業務ルール)


1. 取引先 (Account)

IDルール種別説明
A-001取引先名は必須不変条件name は空文字不可
A-002担当グループは必須ポリシーassignedGroup は必須 (フォーム)
A-003営業担当は必須ポリシーsalesRep は必須 (フォーム)
A-004URL 形式検証検証websitehttps?:// で始まる
A-005電話番号形式検証phone は数字・ハイフン・括弧・スペースのみ
A-006郵便番号形式検証postalCodeXXX-XXXX 形式
A-007楽観ロック不変条件version 不整合で 409 Conflict
A-008計算フィールド読取専用不変条件dealCount, activityCount 等はユーザー変更不可

2. 担当者 (Contact)

IDルール種別説明
C-001担当者名は必須不変条件name は空文字不可
C-002取引先は必須不変条件account は必須。担当者は必ず 1 つの取引先に所属
C-003楽観ロック不変条件version 不整合で 409 Conflict

3. 案件 (Deal)

IDルール種別説明
D-001案件名は必須不変条件name は空文字不可
D-002案件タイプは必須不変条件dealType は negotiation / inquiry / lead のいずれか
D-003ステータスは必須不変条件status は open / won / lost のいずれか (デフォルト: open)
D-004取引先は必須不変条件account は必須。案件は必ず取引先に紐付く
D-005金額は非負検証amount ≥ 0 (nonnegative)
D-006確度は 0-100検証probability は 0 以上 100 以下
D-007楽観ロック不変条件version 不整合で 409 Conflict

案件ステータス遷移

open → won    (成約)
open → lost   (失注)
won → open    (現在は制約なし — 将来的に PMS 連携後は禁止予定)
lost → open   (現在は制約なし)

注意: 現在の実装ではステータス遷移に制約がない。 PMS 連携 (CreateOrderRequest) が発生した won 案件を open に戻すと 整合性の問題が生じる可能性がある。


4. 活動 (Activity)

IDルール種別説明
ACT-001活動タイプは必須不変条件activityType は ACTIVITY_TYPE_VALUES の値のみ
ACT-002件名は必須不変条件subject は空文字不可
ACT-003取引先は必須不変条件account は必須
ACT-004活動日は必須不変条件activityDate は必須
ACT-005所要時間は正の数検証duration > 0 (指定時)
ACT-006件名は 255 文字以内検証subject.length ≤ 255
ACT-007詳細は 2000 文字以内検証description.length ≤ 2000
ACT-008データ必須不変条件data が null/undefined の場合は 400 エラー
ACT-009楽観ロック不変条件version 不整合で 409 Conflict

5. 日報 (Daily Report)

IDルール種別説明
DR-001担当者は必須不変条件user は必須。未指定時は req.user から自動設定
DR-002報告日は必須不変条件reportDate は必須
DR-003同日重複禁止不変条件user + reportDate の組み合わせはユニーク
DR-004RBAC 読取制限ポリシーsales_rep は自分の日報のみ閲覧可
DR-005RBAC 更新制限ポリシーsales_rep は自分の日報のみ編集可
DR-006削除は admin のみポリシーadmin ロールのみ日報削除可能

6. ファイル (File)

IDルール種別説明
F-001ファイル名は必須不変条件fileName は空文字不可
F-002ファイルタイプは必須不変条件fileType は FILE_TYPE_VALUES の値のみ
F-003URL は link 時必須不変条件fileSource=link の場合 url は必須
F-004javascript: 禁止セキュリティurljavascript: プロトコル禁止 (XSS 防止)
F-005http(s) のみセキュリティurlhttp: / https: プロトコルのみ許可
F-006楽観ロック不変条件version 不整合で 409 Conflict

7. ユーザー (User)

IDルール種別説明
U-001ユーザー名は一意不変条件username はシステム全体で一意
U-002ユーザー名パターン不変条件username/^[a-z0-9_]+$/ のみ
U-003ログイン試行制限セキュリティ3 回失敗で 15 分間ロック
U-004トークン有効期限セキュリティ2 時間 (7200 秒)
U-005初回パスワード変更ポリシー新規ユーザーは must_change_password = true
U-006admin のみユーザー作成ポリシーcreate は admin ロールのみ
U-007admin のみユーザー削除ポリシーdelete は admin ロールのみ

8. 企業設定 (Company Settings)

IDルール種別説明
CS-001シングルトン不変条件レコードは 1 件のみ。2 件目作成禁止
CS-002企業名は必須不変条件company_name は必須 (最大 100 文字)
CS-003郵便番号形式検証postal_codeXXX-XXXX
CS-004営業時間形式検証HH:MM 形式 (00:00-23:59)
CS-005営業時間整合性検証start < end
CS-006会計年度月検証fiscal_year_start_month は 1-12 の整数
CS-007admin のみ変更可ポリシーcreate/update/delete は admin のみ
CS-008楽観ロック不変条件version 不整合で 409 Conflict

9. カスタムフィールド (Custom Field Config)

IDルール種別説明
CF-001フィールド名パターン不変条件field_name/^[a-z_][a-z0-9_]*$/
CF-002予約語禁止不変条件field_name に予約語は使用不可
CF-003entity_type + field_name 一意不変条件同一エンティティ内でフィールド名は重複不可
CF-004dropdown はオプション必須検証field_type=dropdown の場合、最低 1 つのオプション
CF-005number の min ≤ max検証min_value > max_value は禁止
CF-006admin のみ操作可ポリシー全操作は admin ロールのみ
CF-007楽観ロック不変条件version 不整合で 409 Conflict

10. RBAC データスコーピング

→ 参照: 03-aggregates/iam.md §RBAC データアクセスマトリクス

IDルール種別説明対象
RBAC-001sales_rep 読取制限ポリシーsales_rep は salesRep = user.id のレコードのみ閲覧可accounts, contacts, deals, activities, files
RBAC-002sales_rep 更新制限ポリシーsales_rep は自分が担当するレコードのみ更新可accounts, contacts, deals, activities, files
RBAC-003executive 読取専用ポリシーexecutive は全レコード閲覧可だが作成・更新・削除不可accounts, contacts, deals, activities, files
RBAC-004manager 全データアクセスポリシーmanager は全レコードの閲覧・作成・更新可、削除は不可accounts, contacts, deals, activities, files
RBAC-005削除は admin のみポリシー営業データコレクションの削除は admin のみaccounts, contacts, deals, activities, files

11. 案件コメント (Comment)

IDルール種別説明
CMT-001案件参照は必須不変条件deal は必須。コメントは必ず案件に紐付く
CMT-002本文は必須不変条件body は空文字不可、最大 2000 文字
CMT-003投稿者自動設定ポリシーauthor は req.user から自動設定
CMT-004削除権限ポリシー削除は投稿者本人または admin のみ
CMT-005commentCount 同期不変条件コメント作成/削除時に Deal.commentCount を更新

12. レポート・分析 (Reporting)

→ 参照: 03-aggregates/reporting.md

IDルール種別説明対象
RPT-001加重金額計算計算weightedAmount = amount x probability / 100PipelineReport
RPT-002成約率計算計算winRate = won / (won + lost) x 100。open のみの場合は 0PipelineReport
RPT-003期間フィルタ必須ポリシーレポートリクエストには startDateendDate が必須PipelineReport, ActivitySummary
RPT-004RBAC スコーピングポリシーsales_rep は自分の担当データのみ集計対象PipelineReport, ActivitySummary
RPT-005読取専用不変条件レポートデータは永続化しない (都度集計)PipelineReport, ActivitySummary

13. 見積書 (Quote)

→ 参照: 03-aggregates/quote-management.md

IDルール種別説明
QT-001テンプレート名は必須不変条件QuoteTemplate.name は空文字不可
QT-002帳票名は必須不変条件QuoteTemplate.documentTitle は空文字不可
QT-003税区分は必須不変条件QuoteTemplate.taxMode は exclusive / inclusive のいずれか
QT-004デフォルトテンプレートは 1 件不変条件isDefault=true のテンプレートはシステム全体で最大 1 件
QT-005テンプレートは admin のみポリシーQuoteTemplate の作成・更新・削除は admin のみ
QT-006見積番号は一意不変条件QuoteDocument.quoteNumber はシステム全体で一意
QT-007案件は必須不変条件QuoteDocument.deal は必須
QT-008明細行は最低 1 行不変条件QuoteDocument.lineItems.length ≥ 1
QT-009品目名は必須検証lineItem.itemName は空文字不可、最大 50 文字
QT-010数量は正の数検証lineItem.quantity > 0
QT-011単価は非負検証lineItem.unitPrice ≥ 0
QT-012有効期限は発行日以降検証QuoteDocument.expiryDate ≥ issueDate
QT-013外税計算計算exclusive: taxAmount = subtotal × 税率、totalAmount = subtotal + taxAmount
QT-014内税計算計算inclusive: taxAmount = subtotal - subtotal / (1 + 税率)、totalAmount = subtotal
QT-015発行後は編集不可不変条件status=issued の見積書は更新不可
QT-016発行時 PDF 生成ポリシーstatus → issued で PDF を生成し File (fileType=quote) として保存
QT-017楽観ロック不変条件version 不整合で 409 Conflict

14. 目標管理 (Goal Tracking)

→ 参照: 03-aggregates/goal-tracking.md

IDルール種別説明
GL-001目標名は必須不変条件Goal.name は空文字不可
GL-002エンティティタイプは必須不変条件Goal.entityType は deals / activities のいずれか
GL-003集計方法は必須不変条件Goal.aggregationMethod は count / sum / average のいずれか
GL-004sum/average 時は対象フィールド必須不変条件aggregationMethod が sum / average の場合、targetField は必須
GL-005対象フィールドは数値型検証targetField は対象エンティティの数値フィールドのみ
GL-006期間は必須不変条件Goal.period は monthly / quarterly / yearly のいずれか
GL-007目標は admin のみポリシーGoal の作成・更新・削除は admin のみ
GL-008目標値は非負検証GoalValue.targetValue ≥ 0
GL-009期間の整合性検証GoalValue.periodStart < periodEnd
GL-010目標値はユニーク不変条件同一 goal + user + periodStart の組み合わせは重複不可
GL-011達成率計算計算achievementRate = actualValue / targetValue × 100
GL-012RBAC スコーピングポリシーsales_rep は自分の担当データのみ集計対象
GL-013楽観ロック不変条件version 不整合で 409 Conflict

15. 重複検出 (Duplicate Detection)

→ 参照: 03-aggregates/sales-pipeline.md §DuplicateDetection

IDルール種別説明
DUP-001自己参照禁止不変条件DuplicateCandidate.sourceId ≠ targetId
DUP-002ペアはユニーク不変条件sourceId + targetId の組み合わせは順序問わず一意
DUP-003スコアは 0-100検証similarityScore は 0 以上 100 以下
DUP-004統合時にメタデータ必須不変条件status=merged の場合、mergedAt と mergedBy は必須
DUP-005統合は admin/manager のみポリシー統合操作は admin または manager ロールのみ
DUP-006統合は関連データ移行を含むポリシー統合時に target の関連 Deal/Contact/Activity/File を source に移行
DUP-007バッチ検出は 1 日 1 回ポリシー自動検出バッチジョブは 1 日 1 回実行

16. カレンダー連携 (Calendar Sync)

→ 参照: 03-aggregates/activity-tracking.md §CalendarSync

IDルール種別説明
CAL-001ユーザー+プロバイダはユニーク不変条件user + provider の組み合わせは一意
CAL-002有効時はトークン必須不変条件isEnabled=true の場合、authToken は必須
CAL-003トークンは暗号化保存セキュリティauthToken は暗号化して保存 (PII)
CAL-004自身の設定のみ管理ポリシー各ユーザーが自身の CalendarSync のみ作成・更新・削除可能
CAL-005アウトバウンド同期のみポリシーActivity → Calendar 方向のみ (初期実装)

17. メール取り込み (Email Capture)

→ 参照: 03-aggregates/activity-tracking.md §EmailCapture

IDルール種別説明
EM-001メールアドレス形式検証emailAddress は有効なメール形式
EM-002ポート範囲検証port は 1-65535 の範囲
EM-003認証情報は暗号化保存セキュリティauthCredentials は暗号化して保存 (PII)
EM-004自身の設定のみ管理ポリシー各ユーザーが自身の EmailCapture のみ管理可能
EM-005Contact マッチングポリシー送信者メールで Contact を検索し、見つかった場合のみ Activity 作成
EM-006活動タイプ自動設定ポリシー取り込みメールの活動タイプは autoActivityType に設定 (デフォルト: email_received)

18. 日報 楽観ロック (Daily Report — 追加ルール)

→ 参照: 03-aggregates/activity-tracking.md §DailyReport

IDルール種別説明
DR-007楽観ロック不変条件version フィールドで更新競合を検出。version 不整合で 409 Conflict

19. カスタムフィールド 影響件数 (Custom Field — 追加ルール)

→ 参照: 03-aggregates/custom-fields.md §AffectedRecordCount

IDルール種別説明
CF-008削除前に影響件数を表示ポリシーカスタムフィールド削除確認時に、そのフィールドを使用中のレコード件数をカウントして表示
CF-009影響件数は都度計算計算affectedRecordCount は永続化せず都度クエリで計算

Appendix. 共通バリデーション定数

バリデーション定数の実装値はインスタンスドキュメント (instances/translead/configuration.md) を参照。