Fab Forward Dev/

DDD ドキュメント

Sales CRM 集約: カスタムフィールド / Aggregate: Custom Fields

バウンデッドコンテキスト: Configuration (設定)


集約ルート

CustomFieldConfig (カスタムフィールド設定)

CustomFieldConfig (集約ルート)
├── entity_type: EntityType       (account / contact / deal)
├── field_name: string            (システム名、snake_case)
├── display_name: string          (ユーザー表示名)
├── field_type: FieldType         (text/number/date/dropdown/checkbox)
├── description: string           (説明)
├── is_required: boolean          (必須フラグ)
├── display_order: number         (表示順)
├── is_system_field: boolean      (システム項目フラグ)
└── type_properties: JSON         (タイプ固有設定)
    ├── options: DropdownOption[]  (dropdown 時)
    ├── min_value: number         (number 時)
    ├── max_value: number         (number 時)
    ├── decimal_places: number    (number 時)
    └── default_value: string     (date 時)
プロパティ必須説明
entity_typeEntityTypeaccount / contact / deal
field_namestringシステム名 (/^[a-z_][a-z0-9_]*$/)
display_namestringユーザー表示名
field_typeFieldTypetext / number / date / dropdown / checkbox
descriptionstring項目の説明
is_requiredboolean必須フラグ (デフォルト: false)
display_ordernumber表示順序 (デフォルト: 0、小さい値が先)
is_system_fieldbooleanシステム標準項目フラグ (読取専用)
type_propertiesJSONタイプ固有の設定プロパティ
createdBy→ User作成者 (読取専用)
updatedBy→ User最終更新者 (読取専用)
versionnumber楽観ロック用

不変条件 (Invariants):

  • entity_type + field_name の組み合わせはユニーク制約
  • field_nameFIELD_NAME_PATTERN に一致: ^[a-z_][a-z0-9_]*$
  • field_name は予約語禁止: id, created_at, updated_at, created_by, updated_by, version, deleted_at, deleted_by
  • dropdown タイプの場合、type_properties.options に最低 1 つのオプションが必要
  • number タイプの場合、min_valuemax_value (両方指定時)
  • admin のみ全操作可能
  • 楽観ロック: バージョン不整合で 409 Conflict

対応するフィールドタイプ

FieldType日本語Payload 型type_properties
textテキストtext
number数値numbermin_value, max_value, decimal_places
date日付datedefault_value
dropdownドロップダウンselectoptions: [{value, label, order}]
checkboxチェックボックスcheckbox

標準フィールド (Standard Fields)

各エンティティには予め定義された標準フィールドがあり、カスタムフィールドと区別される:

EntityType標準フィールド
accountname, website, phone, postalCode, address, coordinates, group, salesRep, dealCount, activityCount, lastActivityAt, nextActivityAt
contactfirstName, lastName, email, phone, position, department, account
dealtitle, amount, stage, probability, expectedCloseDate, account, contact, salesRep

拡張性設計

┌──────────────────┐        ┌──────────────────┐
│ CustomFieldConfig │        │  Account/Contact │
│ (メタデータ)      │───────▶│  /Deal           │
│                  │  動的   │  (実データ)       │
│ entity_type      │  フィールド│                │
│ field_name       │  追加   │  custom_fields:  │
│ field_type       │        │    { [key]: val } │
│ type_properties  │        │                  │
└──────────────────┘        └──────────────────┘

CustomFieldConfig はメタデータ (フィールド定義) を管理し、 実際の値は各エンティティの JSON フィールドに格納される構造。 これにより、スキーマ変更なしに動的な項目追加が可能。


影響件数カウント / Affected Record Count

カスタムフィールド削除前に、そのフィールドを使用しているレコード件数を表示する。

仕様

削除確認ダイアログ表示時に、対象フィールドが使用されているレコード数をカウントする。

クエリ仕様:

対象コレクション = CustomFieldConfig.entity_type に対応するコレクション
  (account → accounts, contact → contacts, deal → deals)

カウント条件:
  WHERE custom_data->>'{field_name}' IS NOT NULL
    AND custom_data->>'{field_name}' != ''

API エンドポイント:

GET /api/settings/custom-fields/:id/impact-count
→ { affectedRecordCount: number }

不変条件 (Invariants):

  • カウントは都度計算 (永続化しない)
  • 削除確認ダイアログでユーザーに件数を表示してから削除実行
  • RBAC: admin のみアクセス可能 (カスタムフィールド操作に準拠)