Skip to content

メール通知システムの実装 #28

@oumelab

Description

@oumelab

イベント申し込みキャンセル機能実装

概要

  • 認証済みユーザーが申し込み済みのイベントをキャンセルできる機能を実装する。
  • ユーザーの利便性向上と、予定変更・急用等への柔軟な対応を可能にする。

目的

  • ユーザーが申し込み後に予定変更した場合の対応
  • 誤申し込みやダブルブッキングの解決
  • 定員管理の柔軟性向上
  • ユーザー体験の大幅改善

背景

現在のシステムでは、一度イベントに申し込むとキャンセルができず、以下の問題が発生している:

  • 急用や予定変更への対応不可
  • 誤申し込み時の修正手段なし
  • 定員に達したイベントでのキャンセル待ち機能なし
  • ユーザーの利便性が低い

実際のイベント管理サービス(connpass等)では申し込みキャンセル機能は標準機能として提供されており、本アプリでも必須の機能と判断。

実装内容

1. バックエンドAPI

  • キャンセルAPI実装(DELETE /api/events/[id]/cancel
  • ユーザー申し込み履歴取得API(GET /api/user/registrations
  • 権限チェック(申し込み者本人のみキャンセル可能)
  • 定員数の自動更新
  • データ整合性の確保

2. メール通知機能

  • キャンセル完了メール(申し込み者へ)
  • キャンセル通知メール(イベント作成者へ)
  • メールテンプレートの作成

3. フロントエンドUI

  • ユーザーの申し込み履歴ページ
  • キャンセルボタンとモーダル
  • キャンセル確認ダイアログ
  • イベント詳細ページでのキャンセル機能
  • 申し込み状況の動的更新

4. UX改善

  • キャンセル理由の選択(オプション)
  • キャンセル期限の設定(イベント開始前のみ等)
  • 申し込み・キャンセル履歴の表示
  • Toast通知による操作フィードバック

技術的詳細

API設計例

キャンセルAPI

// DELETE /api/events/[id]/cancel export async function onRequest(context: RequestContext) { // 1. 認証チェック // 2. 申し込み状況確認 // 3. キャンセル処理実行 // 4. 定員数更新 // 5. メール通知送信 }

申し込み履歴API

// GET /api/user/registrations export async function onRequest(context: RequestContext) { // 1. 認証チェック // 2. ユーザーの申し込み履歴取得 // 3. イベント情報と結合 // 4. キャンセル可能フラグ付与 }

データベース更新

-- attendees テーブルに status カラム追加検討 ALTER TABLE attendees ADD COLUMN status TEXT DEFAULT 'registered'; -- 'registered', 'cancelled' 等の状態管理 -- または論理削除での実装 ALTER TABLE attendees ADD COLUMN cancelled_at INTEGER;

フロントエンド実装例

// ユーザー申し込み履歴表示 function MyRegistrations() { const { data: registrations } = useQuery({ queryKey: ['user-registrations'], queryFn: getUserRegistrations, }); const cancelMutation = useMutation({ mutationFn: cancelEventRegistration, onSuccess: () => { toast.success('申し込みをキャンセルしました'); queryClient.invalidateQueries(['user-registrations']); }, }); return ( <div> {registrations?.map(reg => ( <EventRegistrationCard key={reg.id} registration={reg} onCancel={() => cancelMutation.mutate(reg.event_id)} /> ))} </div> ); }

ユーザーストーリー

基本フロー

1. ユーザーがマイページで申し込み済みイベント一覧を確認 2. キャンセルしたいイベントの「キャンセル」ボタンをクリック 3. 確認ダイアログで理由を選択(オプション) 4. 「キャンセル確定」で処理実行 5. キャンセル完了の通知とメール送信 6. イベント詳細ページで定員数が更新される 

エラーケース

- イベント開始後のキャンセル不可 - 既にキャンセル済みの場合 - 申し込んでいないイベントのキャンセル試行 - 権限のないユーザーによる操作 

受け入れ基準

  • 認証済みユーザーが申し込み済みイベントをキャンセルできる
  • キャンセル後、定員に空きが生まれる
  • キャンセル完了時にメール通知が送信される
  • 申し込み履歴でキャンセル状況が確認できる
  • 不正なキャンセル操作は適切にエラーハンドリングされる
  • イベント詳細ページの参加者数が正確に更新される
  • UXに配慮した確認フローが実装されている

依存関係

前提条件

関連Issue

制約事項

  • イベント開始後のキャンセルは不可
  • キャンセル期限はイベント開始24時間前まで(設定可能)
  • 1つのイベントに対して何度も申し込み・キャンセルを繰り返すことの制限検討

テスト計画

  • 正常系:申し込み→キャンセルの一連フロー
  • 異常系:権限なし、期限切れ、重複操作等
  • 定員管理:キャンセル後の定員数更新確認
  • メール送信:各種通知メールの送信確認
  • UI/UX:操作フローの直感性確認

見積もり

実装時間: 1-2日
テスト時間: 半日

ブランチ

feature/event-registration-cancel

Metadata

Metadata

Assignees

No one assigned

    Labels

    blocked他の機能の実装完了後までfeature新機能の追加priority: medium中優先度

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions