civicship-api 副作用ブレインストーミング
機能変更による副作用・意図しない影響を体系的に洗い出します。見落としがちなエッジケース、ビジネスロジックの連鎖、ユーザーエクスペリエンスへの影響を特定します。
使用方法
bash
# 要件定義書から副作用を洗い出し /side-effect-brainstorming docs/requirements/point-expiration.md # 機能名から副作用を洗い出し /side-effect-brainstorming ポイント有効期限機能 # PRの変更から副作用を洗い出し /side-effect-brainstorming --pr 123
引数:
- •
$ARGUMENTS: 要件定義書のパス、機能名、またはPR番号
副作用分析プロセス
ステップ1: 変更内容の理解
要件や変更内容を分析し、直接的な影響を特定:
markdown
## 変更内容の概要 ### 主要な変更 **機能:** ポイント有効期限機能 **変更内容:** 1. データモデル変更: `t_wallets` に `expiresAt` カラム追加 2. ビジネスロジック変更: ポイント使用時に有効期限チェック 3. バッチ処理追加: 有効期限切れポイントの自動失効 4. 通知機能追加: 有効期限7日前にLINE通知 --- ### 直接的な影響(意図した変更) - [ ] ポイントに有効期限が設定される - [ ] 有効期限切れポイントは使用不可 - [ ] 有効期限切れポイントは自動的に失効 - [ ] ユーザーに事前通知が送られる
ステップ2: データレベルの副作用
データモデル変更による意図しない影響:
markdown
## データレベルの副作用
### データ整合性への影響
#### 副作用1: 既存ポイントの有効期限が未設定
**状況:**
- 既存のウォレットには `expiresAt = null`
- 新規付与ポイントのみ有効期限あり
**問題:**
- 既存ポイントと新規ポイントの扱いが不統一
- ユーザーが混乱する可能性
**影響を受けるユーザー:**
- 既存の全ユーザー(推定: 1,000人)
**推奨対策:**
1. 既存ポイントにも遡及的に有効期限を設定
2. または、既存ポイントは無期限として明示
3. UI で「無期限ポイント」と「期限付きポイント」を区別表示
**優先度:** 🟡 Medium
---
#### 副作用2: 複数のウォレットを持つユーザーの場合
**状況:**
- 将来的に1ユーザーが複数ウォレットを持つ可能性
- ウォレットごとに有効期限が異なる
**問題:**
- どのウォレットから優先的にポイントを使うか不明確
- 有効期限が近いポイントから自動的に使用すべきか?
**推奨対策:**
1. FIFO(First In First Out): 古いポイントから使用
2. 有効期限が近いポイントから優先使用
3. ユーザーが選択できるようにする
**優先度:** 🟢 Low(現状は1ウォレット/ユーザー)
---
### パフォーマンスへの副作用
#### 副作用3: ポイント使用時のクエリ増加
**変更前:**
\`\`\`typescript
// ウォレット取得のみ
const wallet = await this.repo.findByUserId(ctx, userId, tx);
\`\`\`
**変更後:**
\`\`\`typescript
// ウォレット取得 + 有効期限チェック
const wallet = await this.repo.findByUserId(ctx, userId, tx);
if (wallet.expiresAt && wallet.expiresAt < new Date()) {
throw new Error("WALLET_EXPIRED");
}
\`\`\`
**問題:**
- 全てのポイント操作に有効期限チェックが追加
- 処理時間がわずかに増加(数ms程度)
**影響範囲:**
- ポイント送受信
- 特典交換
- Opportunity参加
**推奨対策:**
- 現状は問題なし(メモリ内の日付比較のみ)
- 将来的にキャッシュ検討
**優先度:** 🟢 Low
---
#### 副作用4: バッチ処理の負荷
**状況:**
- 毎日バッチで有効期限切れポイントをチェック
- 全ウォレットをスキャン(推定: 1,000件)
**問題:**
- ウォレット数の増加に伴い処理時間が増加
- 将来的にタイムアウトの可能性
**推奨対策:**
1. インデックス追加: `CREATE INDEX idx_wallets_expires_at ON t_wallets(expiresAt);`
2. バッチを分割実行(100件ずつ)
3. 有効期限が近いもののみクエリ
**優先度:** 🟡 Medium
ステップ3: ビジネスロジックの副作用
ビジネスルール変更による連鎖的な影響:
markdown
## ビジネスロジックの副作用 ### ポイント経済への影響 #### 副作用5: ポイント総流通量の減少 **状況:** - 有効期限切れポイントが失効 - 市場のポイント総量が減少 **問題:** - コミュニティ内のポイント流動性が低下 - Opportunity参加のハードルが上がる **影響を受ける機能:** - Opportunityへの参加率低下の可能性 - 特典交換の減少 **推奨対策:** 1. 失効ポイントのデータを分析 2. 必要に応じてポイント付与量を調整 3. 有効期限の長さを再検討(1年 → 2年など) **優先度:** 🟡 Medium --- #### 副作用6: ポイント送受信への影響 **状況:** - ユーザーAがユーザーBにポイントを送る - 送信直後に送信元のポイントが有効期限切れ **問題:** - 送信したポイントは有効だが、送信元は有効期限切れ - ユーザーの混乱 **シナリオ:** 1. ユーザーA: 残高 100pt(有効期限: 明日) 2. ユーザーAがユーザーBに 50pt 送信 3. 翌日、ユーザーAの残り 50pt が失効 4. ユーザーB の 50pt は有効 **推奨対策:** 1. 送信ポイントに送信元の有効期限を引き継ぐ 2. または、送信ポイントは無期限にする 3. UI で有効期限を明示 **優先度:** 🔴 High(ユーザー体験に直結) --- ### 例外処理の副作用 #### 副作用7: エラーハンドリングの追加 **状況:** - `WALLET_EXPIRED` エラーが新たに発生 **問題:** - 既存のエラーハンドリングが対応していない - クライアント側で未対応のエラー **影響範囲:** - GraphQL Resolver - クライアント(iOS, Android, Web) **推奨対策:** 1. GraphQLエラーレスポンスに `WALLET_EXPIRED` を追加 2. クライアント側でエラーメッセージ表示 3. ユーザーに「ポイントが有効期限切れです」と通知 **優先度:** 🔴 High --- ### トランザクションの副作用 #### 副作用8: トランザクション中の有効期限切れ **状況:** - トランザクション開始時は有効だったポイント - トランザクション中に有効期限切れ **シナリオ:** 1. トランザクション開始(12:59:59) 2. ポイント有効期限(13:00:00) 3. トランザクション処理中(13:00:01) 4. 有効期限チェック → エラー **問題:** - タイミングによってトランザクションが失敗 - ユーザーの混乱 **推奨対策:** 1. トランザクション開始時の有効期限で判定 2. トランザクション中は有効期限を再チェックしない 3. または、有効期限に猶予時間を設ける(+1時間など) **優先度:** 🟡 Medium
ステップ4: ユーザーエクスペリエンスの副作用
UXへの意図しない影響:
markdown
## UXレベルの副作用 ### ユーザー心理への影響 #### 副作用9: ポイント失効への不満 **状況:** - ユーザーが知らないうちにポイントが失効 - 通知を見逃した場合、突然ポイントが消える **問題:** - ユーザーの不信感 - アプリの評価低下 - 解約率の増加 **推奨対策:** 1. 失効7日前、3日前、1日前の3回通知 2. アプリ内通知 + LINE通知のダブル通知 3. 失効後30日間は復元可能にする(ゴミ箱機能) 4. 失効ポイントの履歴を表示 **優先度:** 🔴 High(ユーザー満足度に直結) --- #### 副作用10: ポイント貯蓄行動の変化 **状況:** - 有効期限があるため、ユーザーがポイントを貯めにくくなる - 早めに使い切る行動 **影響:** - 高額特典の交換率低下 - ポイント経済の活性化(ポジティブな副作用) **推奨対策:** - ポイント使用率のデータ分析 - 必要に応じて有効期限を調整 **優先度:** 🟢 Low(分析後に判断) --- ### UIへの副作用 #### 副作用11: UI表示の複雑化 **変更前:** \`\`\` ポイント残高: 1,000pt \`\`\` **変更後:** \`\`\` ポイント残高: 1,000pt 有効期限: 2026-12-31 \`\`\` **問題:** - 表示項目が増加 - UI が煩雑になる **影響範囲:** - ウォレット表示画面 - ポイント送受信画面 - 特典交換画面 **推奨対策:** 1. 有効期限が近い場合のみ表示(残り30日以内) 2. アイコン+ツールチップで簡潔に表示 3. 詳細画面で有効期限一覧を表示 **優先度:** 🟡 Medium
ステップ5: 外部システムへの副作用
外部サービスや連携システムへの影響:
markdown
## 外部システムへの副作用 ### LINE通知への影響 #### 副作用12: 通知量の増加 **状況:** - 有効期限7日前に全ユーザーに通知 - ユーザー数 1,000人 → 1,000通/週 **問題:** - LINE API のレート制限 - 通知コストの増加 **影響範囲:** - LINE Messaging API - 通知バッチ処理 **推奨対策:** 1. バッチを分散実行(1日100人ずつ) 2. LINE API のレート制限を確認 3. オプトアウト機能の提供 **優先度:** 🟡 Medium --- #### 副作用13: 通知の過剰配信 **状況:** - ユーザーが複数のウォレットを持つ場合 - ウォレットごとに通知が送られる **問題:** - 同じユーザーに複数の通知 - 通知疲れ **推奨対策:** - 1ユーザーにつき1日1通までに制限 - 複数ウォレットの有効期限をまとめて通知 **優先度:** 🟢 Low(現状は1ウォレット/ユーザー) --- ### 分析ツールへの影響 #### 副作用14: ポイント残高の集計への影響 **状況:** - ポイント総流通量の集計 - 有効期限切れポイントを含むか含まないか **問題:** - 集計結果の不一致 - レポートの誤解 **推奨対策:** - 集計クエリを「有効ポイントのみ」に修正 - ダッシュボードに「失効ポイント」を別表示 **優先度:** 🟡 Medium
ステップ6: 運用への副作用
運用面での意図しない影響:
markdown
## 運用レベルの副作用 ### カスタマーサポートへの影響 #### 副作用15: 問い合わせ増加 **予想される問い合わせ:** 1. 「ポイントが消えた」 2. 「有効期限はいつ?」 3. 「有効期限を延長できないか」 4. 「通知が来なかった」 5. 「失効したポイントを復元してほしい」 **影響:** - カスタマーサポートの負荷増加 - 推定: 月30件 → 80件(+50件) **推奨対策:** 1. FAQの整備 2. アプリ内ヘルプの追加 3. カスタマーサポート向けマニュアル作成 4. 失効ポイント復元フローの策定 **優先度:** 🟡 Medium --- ### 管理画面への影響 #### 副作用16: 管理機能の追加必要 **不足している機能:** - [ ] 有効期限の一括設定 - [ ] 有効期限の延長 - [ ] 失効ポイントの復元 - [ ] 有効期限のレポート **推奨対策:** - 管理者向け機能を Phase 2 として追加実装 **優先度:** 🟡 Medium
ステップ7: 法的・コンプライアンスの副作用
法的リスクや規約への影響:
markdown
## 法的・コンプライアンスの副作用 ### 利用規約への影響 #### 副作用17: 利用規約の更新必要 **現在の利用規約:** - ポイントの有効期限に関する記載なし **問題:** - 利用規約違反の可能性 - ユーザーとのトラブル **推奨対策:** 1. 利用規約に有効期限条項を追加 2. ユーザーへの事前通知(30日前) 3. 利用規約への同意を再取得 **優先度:** 🔴 Critical(法的リスク) --- ### 会計への影響 #### 副作用18: ポイント引当金の会計処理 **状況:** - ポイントは将来的な負債として計上 - 有効期限切れポイントは負債から除外可能 **影響:** - 会計処理の変更 - 財務諸表への影響 **推奨対策:** - 経理部門と調整 - 会計士に相談 **優先度:** 🟡 Medium(財務への影響確認)
ステップ8: 将来の機能への副作用
将来計画している機能への影響:
markdown
## 将来の機能への副作用 ### 計画中の機能への影響 #### 副作用19: ポイント交換機能への影響 **計画中の機能:** - 複数コミュニティ間のポイント交換 - ポイントを他ユーザーにギフト **問題:** - 交換したポイントの有効期限はどうなるか - 送信元の有効期限を引き継ぐか、新たに設定するか **推奨対策:** - 有効期限のポリシーを事前に決定 - 柔軟に対応できるデータモデル設計 **優先度:** 🟢 Low(将来機能) --- #### 副作用20: ポイント統合への影響 **計画中の機能:** - 複数のウォレットを統合 - ポイントをマージ **問題:** - 異なる有効期限のポイントをどうマージするか - 最短の有効期限を採用? 加重平均? **推奨対策:** - ポイントごとに有効期限を保持 - マージ時にユーザーに選択させる **優先度:** 🟢 Low(将来機能)
ステップ9: エッジケースの洗い出し
極端な状況や例外的なケース:
markdown
## エッジケース ### 境界値のケース #### ケース1: 有効期限が過去の日付 **状況:** - データ移行ミスで `expiresAt = 2020-01-01` - システムが正常に動作するか **推奨対策:** - データバリデーション - 過去の日付は即座にエラー --- #### ケース2: 有効期限が100年後 **状況:** - バグで `expiresAt = 2126-01-01` - 実質的に無期限 **推奨対策:** - 有効期限の最大値を制限(例: 10年後まで) - バリデーションで弾く --- #### ケース3: 有効期限が null **状況:** - 既存ポイントの `expiresAt = null` - 無期限として扱うか、エラーとするか **推奨対策:** - `null = 無期限` と明確に定義 - ドキュメントに記載 --- ### 同時実行のケース #### ケース4: 有効期限切れの瞬間にポイント使用 **状況:** - 13:00:00 に有効期限切れ - 12:59:59 にポイント送信開始 - 13:00:01 にトランザクション完了 **推奨対策:** - トランザクション開始時の有効期限で判定 - または、秒単位ではなく日単位で判定(EOD: End of Day) --- ### データ量の極端なケース #### ケース5: 100万ユーザーのバッチ処理 **状況:** - ユーザー数が急増 - バッチ処理がタイムアウト **推奨対策:** - スケーラビリティを考慮した設計 - バッチを分割実行
ステップ10: 副作用マップの生成
全ての副作用を優先度付きでまとめ:
markdown
# 副作用分析レポート **機能:** ポイント有効期限機能 **分析日:** YYYY-MM-DD **検出された副作用:** 20件 --- ## エグゼクティブサマリー ### 優先度別の副作用 - **🔴 Critical:** 3件(即座に対処必須) - **🟡 Medium:** 10件(リリース前に対処推奨) - **🟢 Low:** 7件(将来的に対処) ### カテゴリ別の副作用 | カテゴリ | 副作用数 | |---------|---------| | データ整合性 | 2件 | | パフォーマンス | 2件 | | ビジネスロジック | 3件 | | UX | 3件 | | 外部システム | 2件 | | 運用 | 2件 | | 法的・コンプライアンス | 2件 | | 将来機能 | 2件 | | エッジケース | 2件 | --- ## 🔴 Critical(即座に対処) | # | 副作用 | 影響 | 対策 | 工数 | |---|--------|------|------|------| | 6 | ポイント送受信への影響 | ユーザー体験 | 送信ポイントに有効期限引き継ぎ | 4h | | 7 | エラーハンドリング未対応 | システムエラー | クライアント側対応 | 6h | | 9 | ポイント失効への不満 | ユーザー満足度 | 通知強化、復元機能 | 8h | | 17 | 利用規約の未更新 | 法的リスク | 規約更新、同意取得 | 4h | **Total:** 22時間 --- ## 🟡 Medium(リリース前に対処推奨) [10件の副作用リスト...] **Total:** 35時間 --- ## 🟢 Low(将来的に対処) [7件の副作用リスト...] **Total:** 15時間 --- ## 推奨アクション ### Phase 1: Critical 対応(Week 1-2) 1. ポイント送受信の有効期限ロジック修正 2. エラーハンドリング追加 3. 通知・復元機能の実装 4. 利用規約の更新 ### Phase 2: Medium 対応(Week 3-4) 5-14. Medium 優先度の副作用対応 ### Phase 3: Low 対応(Month 2-3) 15-20. Low 優先度の副作用対応 --- ## 承認 - [ ] プロダクトオーナー - [ ] テックリード - [ ] UXデザイナー - [ ] 法務担当
活用例
例1: 新機能の副作用分析
bash
/side-effect-brainstorming ポイント有効期限機能
出力:
- •20件の副作用
- •優先度付き
- •対策提案
例2: PRの副作用チェック
bash
/side-effect-brainstorming --pr 123
出力:
- •コード変更による副作用
- •影響範囲の可視化
注意事項
副作用分析の限界
- •❌ 全ての副作用を網羅することは不可能
- •❌ ビジネスドメイン固有の知識が必要
- •❌ 実運用後に判明する副作用もある
推奨される併用スキル
- •
/check-requirement-delta- 既存仕様との衝突検出 - •
/map-impact-analysis- 技術的な影響範囲 - •
/phased-delivery-plan- 段階的リリースで副作用を最小化
参考資料
以下については @CLAUDE.md を参照してください:
- •ビジネスロジックのパターン
- •エラーハンドリング戦略
- •UXベストプラクティス