---
generated_at: 2026-01-29 12:00:00
metrics:
  claims_total: 135
  claims_with_evidence: 135
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：member.csv

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：135 / 135、根拠なし：0
- 優先レビュー（高）
  1. **なし**：すべてのテストケースにソースコード根拠あり

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `ghost/core/core/server/models/member.js`
- E-02: `ghost/core/core/server/models/member-newsletter.js`
- E-03: `ghost/core/core/server/models/member-cancel-event.js`
- E-04: `ghost/core/core/server/models/member-click-event.js`
- E-05: `ghost/core/core/server/models/member-created-event.js`
- E-06: `ghost/core/core/server/models/member-email-change-event.js`
- E-07: `ghost/core/core/server/models/member-feedback.js`
- E-08: `ghost/core/core/server/models/member-login-event.js`
- E-09: `ghost/core/core/server/models/member-paid-subscription-event.js`
- E-10: `ghost/core/core/server/models/member-payment-event.js`
- E-11: `ghost/core/core/server/models/member-product-event.js`
- E-12: `ghost/core/core/server/models/member-status-event.js`
- E-13: `ghost/core/core/server/models/member-stripe-customer.js`
- E-14: `ghost/core/core/server/models/member-subscribe-event.js`
- E-15: `ghost/core/core/server/models/label.js`

## 3) Claims と根拠の対応（レビューの主戦場）

### Member モデル（UT-MEM-001 〜 UT-MEM-044）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | デフォルト値が正しく設定されること | E-01: L13-22 `defaults()` | ○ |
| C-02 | フィルター展開が正しく定義されていること | E-01: L24-65 `filterExpansions()` | ○ |
| C-03 | フィルターリレーションが正しく定義されていること | E-01: L67-139 `filterRelations()` | ○ |
| C-04 | Product belongsToManyリレーションが取得できること | E-01: L171-180 `products()` | ○ |
| C-05 | 製品未紐付け時に空配列が返却されること | E-01: L171-180 `products()` リレーション定義 | ○ |
| C-06 | Newsletter belongsToManyリレーションが取得できること | E-01: L182-190 `newsletters()` | ○ |
| C-07 | Label belongsToManyリレーションが取得できること | E-01: L197-206 `labels()` | ○ |
| C-08 | StripeCustomer hasManyリレーションが取得できること | E-01: L208-210 `stripeCustomers()` | ○ |
| C-09 | StripeSubscription belongsToManyリレーションが取得できること | E-01: L212-221 `stripeSubscriptions()` | ○ |
| C-10 | EmailRecipient hasManyリレーションが取得できること | E-01: L223-225 `email_recipients()` | ○ |
| C-11 | MemberProductEvent hasManyリレーションが取得できること | E-01: L166-169 `productEvents()` | ○ |
| C-12 | OfferRedemption hasManyリレーションが取得できること | E-01: L192-195 `offerRedemptions()` | ○ |
| C-13 | 製品有効期限が正しく更新されること | E-01: L227-237 `updateTierExpiry()` | ○ |
| C-14 | 空配列時に何も更新されないこと | E-01: L227-237 `updateTierExpiry()` forループ | ○ |
| C-15 | product.idがnullの場合にスキップされること | E-01: L229 `if (product?.id)` | ○ |
| C-16 | stripeSubscriptionsがsubscriptionsにリネームされること | E-01: L239-248 `serialize()` | ○ |
| C-17 | member.addedイベントが発火されること | E-01: L250-253 `emitChange()` | ○ |
| C-18 | メンバー作成時にaddedイベントが発火されること | E-01: L255-259 `onCreated()` | ○ |
| C-19 | メンバー更新時にeditedイベントが発火されること | E-01: L261-265 `onUpdated()` | ○ |
| C-20 | メンバー削除時にdeletedイベントが発火されること | E-01: L267-271 `onDestroyed()` | ○ |
| C-21 | ラベルの重複が除去されること | E-01: L279-304 `onSaving()` ラベル重複除去ロジック | ○ |
| C-22 | 既存ラベルとの名前マッチングが行われること | E-01: L309-323 `onSaving()` 既存ラベル検索 | ○ |
| C-23 | labelsがundefinedの場合はunsetされること | E-01: L282-285 `if (_.isUndefined(this.get('labels')))` | ○ |
| C-24 | ラベル追加時にattachedイベントが発火されること | E-01: L340-347 `handleAttachedModels()` | ○ |
| C-25 | ラベル削除時にdetachedイベントが発火されること | E-01: L333-338 `handleAttachedModels()` | ○ |
| C-26 | リレーションキーが許可属性に追加されること | E-01: L355-363 `permittedAttributes()` | ○ |
| C-27 | edit/add/destroyでlabelsリレーションが含まれること | E-01: L371-377 `defaultRelations()` | ○ |
| C-28 | name検索が正しく動作すること | E-01: L379-384 `searchQuery()` | ○ |
| C-29 | email検索が正しく動作すること | E-01: L379-384 `searchQuery()` | ○ |
| C-30 | email_open_rateでのソートが正しく動作すること | E-01: L386-392 `orderRawQuery()` | ○ |
| C-31 | email_open_rate以外ではundefinedが返却されること | E-01: L386-392 `orderRawQuery()` if条件 | ○ |
| C-32 | Gravatar URLが生成されること | E-01: L394-407 `toJSON()` | ○ |
| C-33 | Gravatarが無効の場合はnullが設定されること | E-01: L401 `!config.isPrivacyDisabled('useGravatar')` | ○ |
| C-34 | emailがnullの場合はavatar_imageがnullになること | E-01: L401 `if (attrs.email && ...)` | ○ |
| C-35 | findPageでsearchオプションが許可されること | E-01: L414-422 `permittedOptions()` | ○ |
| C-36 | トランザクション内でメンバーが追加されること | E-01: L424-437 `add()` | ○ |
| C-37 | 製品紐付けと有効期限更新が同時に行われること | E-01: L431-434 `add()` updateTierExpiry呼び出し | ○ |
| C-38 | トランザクション内でメンバーが編集されること | E-01: L439-452 `edit()` | ○ |
| C-39 | 製品有効期限が更新されること | E-01: L446-449 `edit()` updateTierExpiry呼び出し | ○ |
| C-40 | トランザクション内でメンバーが削除されること | E-01: L454-461 `destroy()` | ○ |
| C-41 | 指定ラベルIDとメンバーIDsの紐付けが取得されること | E-01: L463-474 `getLabelRelations()` | ○ |
| C-42 | 購読中メンバーIDが取得されること | E-01: L476-492 `fetchAllSubscribed()` | ○ |
| C-43 | email_disabledメンバーが除外されること | E-01: L483 `'members.email_disabled': false` | ○ |
| C-44 | 非アクティブニュースレター購読者が除外されること | E-01: L482 `'newsletters.status': 'active'` | ○ |

### MemberNewsletter モデル（UT-MEM-045）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-45 | テーブル名が正しく設定されていること | E-02: L4 `tableName: 'members_newsletters'` | ○ |

### MemberCancelEvent モデル（UT-MEM-046 〜 UT-MEM-048）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-46 | Member belongsToリレーションが取得できること | E-03: L7-9 `member()` | ○ |
| C-47 | edit呼び出しでIncorrectUsageErrorがスローされること | E-03: L11-13 `edit()` | ○ |
| C-48 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-03: L15-17 `destroy()` | ○ |

### MemberClickEvent モデル（UT-MEM-049 〜 UT-MEM-056）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-49 | Redirect belongsToリレーションが取得できること | E-04: L7-9 `link()` | ○ |
| C-50 | Member belongsToリレーションが取得できること | E-04: L11-13 `member()` | ○ |
| C-51 | post_idフィルター展開が定義されていること | E-04: L15-22 `filterExpansions()` | ○ |
| C-52 | linkリレーションが定義されていること | E-04: L24-39 `filterRelations()` | ○ |
| C-53 | filterRelations=falseで空オブジェクトが返却されること | E-04: L25-27 `if (options && options.filterRelations === false)` | ○ |
| C-54 | edit呼び出しでIncorrectUsageErrorがスローされること | E-04: L42-44 `edit()` | ○ |
| C-55 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-04: L46-48 `destroy()` | ○ |
| C-56 | findPageで追加オプションが許可されること | E-04: L50-61 `permittedOptions()` | ○ |

### MemberCreatedEvent モデル（UT-MEM-057 〜 UT-MEM-064）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-57 | Member belongsToリレーションが取得できること | E-05: L7-9 `member()` | ○ |
| C-58 | SubscriptionCreatedEvent belongsToリレーションが取得できること | E-05: L14-16 `subscriptionCreatedEvent()` | ○ |
| C-59 | Post belongsToリレーションが取得できること | E-05: L18-20 `postAttribution()` | ○ |
| C-60 | User belongsToリレーションが取得できること | E-05: L22-24 `userAttribution()` | ○ |
| C-61 | Tag belongsToリレーションが取得できること | E-05: L26-28 `tagAttribution()` | ○ |
| C-62 | subscriptionCreatedEventリレーションが定義されていること | E-05: L30-44 `filterRelations()` | ○ |
| C-63 | edit呼び出しでIncorrectUsageErrorがスローされること | E-05: L46-48 `edit()` | ○ |
| C-64 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-05: L50-52 `destroy()` | ○ |

### MemberEmailChangeEvent モデル（UT-MEM-065 〜 UT-MEM-067）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-65 | Member belongsToリレーションが取得できること | E-06: L7-9 `member()` | ○ |
| C-66 | edit呼び出しでIncorrectUsageErrorがスローされること | E-06: L11-13 `edit()` | ○ |
| C-67 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-06: L15-17 `destroy()` | ○ |

### MemberFeedback モデル（UT-MEM-068 〜 UT-MEM-070）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-68 | Post belongsToリレーションが取得できること | E-07: L7-9 `post()` | ○ |
| C-69 | Member belongsToリレーションが取得できること | E-07: L11-13 `member()` | ○ |
| C-70 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-07: L15-17 `destroy()` | ○ |

### MemberLoginEvent モデル（UT-MEM-071 〜 UT-MEM-073）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-71 | Member belongsToリレーションが取得できること | E-08: L7-9 `member()` | ○ |
| C-72 | edit呼び出しでIncorrectUsageErrorがスローされること | E-08: L11-13 `edit()` | ○ |
| C-73 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-08: L15-17 `destroy()` | ○ |

### MemberPaidSubscriptionEvent モデル（UT-MEM-074 〜 UT-MEM-083）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-74 | Member belongsToリレーションが取得できること | E-09: L7-9 `member()` | ○ |
| C-75 | StripeCustomerSubscription belongsToリレーションが取得できること | E-09: L11-13 `stripeSubscription()` | ○ |
| C-76 | SubscriptionCreatedEvent belongsToリレーションが取得できること | E-09: L15-17 `subscriptionCreatedEvent()` | ○ |
| C-77 | aggregateMRRDeltasで日別MRR集計が行われること | E-09: L19-31 `customQuery()` | ○ |
| C-78 | aggregateMRRDeltasとlimit併用でエラーがスローされること | E-09: L21-23 `if (options.limit || options.filter)` | ○ |
| C-79 | aggregateMRRDeltasとfilter併用でエラーがスローされること | E-09: L21-23 `if (options.limit || options.filter)` | ○ |
| C-80 | subscriptionCreatedEventリレーションが定義されていること | E-09: L34-47 `filterRelations()` | ○ |
| C-81 | findAllでaggregateMRRDeltasが許可されること | E-09: L49-57 `permittedOptions()` | ○ |
| C-82 | edit呼び出しでIncorrectUsageErrorがスローされること | E-09: L58-60 `edit()` | ○ |
| C-83 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-09: L62-64 `destroy()` | ○ |

### MemberPaymentEvent モデル（UT-MEM-084 〜 UT-MEM-090）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-84 | Member belongsToリレーションが取得できること | E-10: L7-9 `member()` | ○ |
| C-85 | aggregatePaymentVolumeで日別支払量集計が行われること | E-10: L11-24 `customQuery()` | ○ |
| C-86 | aggregatePaymentVolumeとlimit併用でエラーがスローされること | E-10: L13-15 `if (options.limit || options.filter)` | ○ |
| C-87 | aggregatePaymentVolumeとfilter併用でエラーがスローされること | E-10: L13-15 `if (options.limit || options.filter)` | ○ |
| C-88 | findAllでaggregatePaymentVolumeが許可されること | E-10: L26-34 `permittedOptions()` | ○ |
| C-89 | edit呼び出しでIncorrectUsageErrorがスローされること | E-10: L35-37 `edit()` | ○ |
| C-90 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-10: L39-41 `destroy()` | ○ |

### MemberProductEvent モデル（UT-MEM-091 〜 UT-MEM-094）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-91 | Member belongsToリレーションが取得できること | E-11: L12-14 `member()` | ○ |
| C-92 | Product belongsToリレーションが取得できること | E-11: L16-18 `product()` | ○ |
| C-93 | edit呼び出しでIncorrectUsageErrorがスローされること | E-11: L21-25 `edit()` | ○ |
| C-94 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-11: L27-31 `destroy()` | ○ |

### MemberStatusEvent モデル（UT-MEM-095 〜 UT-MEM-104）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-95 | Member belongsToリレーションが取得できること | E-12: L7-9 `member()` | ○ |
| C-96 | aggregateStatusCountsで日別ステータス集計が行われること | E-12: L11-38 `customQuery()` | ○ |
| C-97 | paid_deltaが正しく計算されること | E-12: L21-25 CASE文 | ○ |
| C-98 | comped_deltaが正しく計算されること | E-12: L26-30 CASE文 | ○ |
| C-99 | free_deltaが正しく計算されること | E-12: L31-35 CASE文 | ○ |
| C-100 | aggregateStatusCountsとlimit併用でエラーがスローされること | E-12: L13-17 `if (options.limit || options.filter)` | ○ |
| C-101 | aggregateStatusCountsとfilter併用でエラーがスローされること | E-12: L13-17 `if (options.limit || options.filter)` | ○ |
| C-102 | findAllでaggregateStatusCountsが許可されること | E-12: L41-49 `permittedOptions()` | ○ |
| C-103 | edit呼び出しでIncorrectUsageErrorがスローされること | E-12: L50-52 `edit()` | ○ |
| C-104 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-12: L54-56 `destroy()` | ○ |

### MemberStripeCustomer モデル（UT-MEM-105 〜 UT-MEM-111）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-105 | StripeCustomerSubscription hasManyリレーションが取得できること | E-13: L12-14 `subscriptions()` | ○ |
| C-106 | Member belongsToリレーションが取得できること | E-13: L16-18 `member()` | ○ |
| C-107 | 既存顧客の場合はeditが呼ばれること | E-13: L20-29 `upsert()` | ○ |
| C-108 | 新規顧客の場合はaddが呼ばれること | E-13: L28 `return this.add(data, unfilteredOptions)` | ○ |
| C-109 | トランザクション内で追加が行われること | E-13: L31-38 `add()` | ○ |
| C-110 | トランザクション内で編集が行われること | E-13: L40-47 `edit()` | ○ |
| C-111 | トランザクション内で削除が行われること | E-13: L49-56 `destroy()` | ○ |

### MemberSubscribeEvent モデル（UT-MEM-112 〜 UT-MEM-120）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-112 | Member belongsToリレーションが取得できること | E-14: L7-9 `member()` | ○ |
| C-113 | Newsletter belongsToリレーションが取得できること | E-14: L11-13 `newsletter()` | ○ |
| C-114 | aggregateSubscriptionDeltasで日別購読数集計が行われること | E-14: L15-29 `customQuery()` | ○ |
| C-115 | subscribed_deltaが正しく計算されること | E-14: L25 `SUM(CASE WHEN subscribed THEN 1 ELSE -1 END)` | ○ |
| C-116 | aggregateSubscriptionDeltasとlimit併用でエラーがスローされること | E-14: L17-20 `if (options.limit || options.filter)` | ○ |
| C-117 | aggregateSubscriptionDeltasとfilter併用でエラーがスローされること | E-14: L17-20 `if (options.limit || options.filter)` | ○ |
| C-118 | findAllでaggregateSubscriptionDeltasが許可されること | E-14: L31-39 `permittedOptions()` | ○ |
| C-119 | edit呼び出しでIncorrectUsageErrorがスローされること | E-14: L40-43 `edit()` | ○ |
| C-120 | destroy呼び出しでIncorrectUsageErrorがスローされること | E-14: L45-49 `destroy()` | ○ |

### Label モデル（UT-MEM-121 〜 UT-MEM-135）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-121 | label.addedイベントが発火されること | E-15: L19-22 `emitChange()` | ○ |
| C-122 | ラベル作成時にaddedイベントが発火されること | E-15: L24-28 `onCreated()` | ○ |
| C-123 | ラベル更新時にeditedイベントが発火されること | E-15: L30-34 `onUpdated()` | ○ |
| C-124 | ラベル削除時にdeletedイベントが発火されること | E-15: L36-40 `onDestroyed()` | ○ |
| C-125 | ラベル名がトリムされること | E-15: L47-48 `let name = this.get('name') && this.get('name').trim()` | ○ |
| C-126 | slugが自動生成されること | E-15: L49-56 `if (this.hasChanged('slug') || ...)` | ○ |
| C-127 | 既存slugがある場合は正規化されること | E-15: L51-55 `generateSlug()` | ○ |
| C-128 | Member belongsToManyリレーションが取得できること | E-15: L59-61 `members()` | ○ |
| C-129 | JSON変換が正しく行われること | E-15: L63-66 `toJSON()` | ○ |
| C-130 | デフォルトソート順が正しく設定されていること | E-15: L68-73 `orderDefaultOptions()` | ○ |
| C-131 | findAllでcolumnsオプションが許可されること | E-15: L75-91 `permittedOptions()` | ○ |
| C-132 | destroyでdestroyAllオプションが許可されること | E-15: L75-91 `permittedOptions()` | ○ |
| C-133 | メンバー数カウントサブクエリが正しく生成されること | E-15: L93-105 `countRelations()` | ○ |
| C-134 | ラベル削除前にメンバー紐付けが解除されること | E-15: L107-126 `destroy()` | ○ |
| C-135 | 存在しないラベル削除でNotFoundErrorがスローされること | E-15: L114-117 `if (!label)` | ○ |

## 4) 不足情報（Unknown / Missing）
- なし：すべてのテストケースに対してソースコードから根拠を確認できました

## 5) リスクフラグ（レビュー観点）
- **0: 低リスク** - すべてのテストケースがソースコードに基づいて生成されている

## 6) レビュアーチェックリスト（最小）
- [ ] Memberモデルのdefaults()でstatus='free'が適切か確認
- [ ] Memberモデルのリレーション（products, newsletters, labels）がデータベーススキーマと一致しているか確認
- [ ] イベントモデル（CancelEvent, ClickEvent等）のedit/destroy禁止が業務要件と一致しているか確認
- [ ] customQuery()のSQL集計ロジックがデータベースエンジン間で互換性があるか確認
- [ ] MemberStripeCustomerのupsert()がトランザクション分離レベルに適切か確認
- [ ] Labelモデルのdestroy()でメンバー紐付け解除のパフォーマンスが許容範囲か確認
