-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Labels
blocked他の機能の実装完了後まで他の機能の実装完了後までblocking他の Issue をブロック中他の Issue をブロック中feature新機能の追加新機能の追加priority: medium中優先度中優先度
Description
Issue #5: イベント申し込み・キャンセル機能の実装
概要
認証済みユーザーがイベントに申し込み、キャンセルできる機能を実装する。申し込み履歴の確認も含め、イベント参加管理の核心機能を提供する。
目的
- 認証済みユーザーのみがイベントへの参加を申し込める
- 認証済みユーザーは申し込み済みのイベントをキャンセルできる
- 認証済みユーザーは自分のイベント申し込み履歴を確認できる
- 定員管理と重複申し込み防止を実現する
- イベント参加のライフサイクル全体をサポートする
依存関係
前提条件
以下のIssueが完了していることが前提:
- Issue 認証機能の実装 #3 (認証機能の実装)
- Issue イベント情報管理CRUD機能の実装 #4 (イベントCRUD API実装)
- Issue イベント管理フォーム実装 #17 (イベント管理フォーム実装)
後続Issue
このIssueの完了は以下のIssueの前提条件となる:
- Issue メール通知システムの実装 #28 (メール通知システムの実装)
- Issue イベント参加者管理機能の実装 #6 (イベント参加者管理機能の実装)
実装内容
1. バックエンドAPI実装
-
申し込みAPI:
POST /api/events/[id]/apply
- 認証チェック(ログイン済みユーザーのみ)
- 定員チェック(満員の場合エラー)
- 重複チェック(同一ユーザーの重複申し込み防止)
- attendeesテーブルへのレコード挿入
- レスポンス返却
-
キャンセルAPI:
DELETE /api/events/[id]/cancel
- 認証チェック(申し込み者本人のみ)
- キャンセル可能期間チェック(イベント開始前のみ)
- attendeesテーブルからのレコード削除
- 定員数の自動更新
-
申し込み履歴API:
GET /api/user/registrations
- 認証チェック
- ユーザーの申し込み履歴取得
- イベント情報との結合
- キャンセル可能フラグの付与
2. データベース設計
- attendeesテーブルの拡張
-- user_idカラムが未追加の場合 ALTER TABLE attendees ADD COLUMN user_id TEXT REFERENCES users(id); -- インデックス追加 CREATE INDEX idx_attendees_user_id ON attendees(user_id); CREATE INDEX idx_attendees_event_user ON attendees(event_id, user_id);
3. フロントエンド実装
-
申し込み機能UI
- イベント詳細ページでの申し込みボタン
- 認証状態に基づく表示制御
- 申し込み済み・満員時の状態表示
- ローディング・エラー状態の表示
-
キャンセル機能UI
- 申し込み履歴ページでのキャンセルボタン
- キャンセル確認ダイアログ
- キャンセル理由選択(オプション)
- 処理中・完了状態の表示
-
申し込み履歴ページ
- ユーザーの申し込みイベント一覧
- イベント情報の表示
- 申し込み日時の表示
- キャンセル可能状態の判定・表示
4. 状態管理・API統合
-
TanStack Queryによるデータ管理
- 申し込み状態のキャッシュ管理
- 楽観的更新の実装
- エラー時のロールバック
- 関連データの自動更新
-
Zustandとの連携
- 申し込み状態の グローバル管理
- UI状態の同期
- ユーザー体験の向上
技術的詳細
API設計例
// 申し込みAPI
POST /api/events/[id]/apply
Request: {}
Response: {
success: boolean;
message: string;
registration: {
id: string;
event_id: string;
user_id: string;
email: string;
created_at: number;
};
}
// キャンセルAPI
DELETE /api/events/[id]/cancel
Response: {
success: boolean;
message: string;
cancelled_registration_id: string;
}
// 申し込み履歴API
GET /api/user/registrations
Response: {
registrations: Array<{
id: string;
event: Event;
registered_at: number;
can_cancel: boolean;
}>;
}
フロントエンド実装例
// 申し込み処理
const applyMutation = useMutation({
mutationFn: (eventId: string) => applyToEvent(eventId),
onSuccess: () => {
toast.success('イベントに申し込みました');
queryClient.invalidateQueries(['events']);
queryClient.invalidateQueries(['user-registrations']);
},
onError: (error) => {
toast.error(error.message);
},
});
// キャンセル処理
const cancelMutation = useMutation({
mutationFn: (eventId: string) => cancelEventRegistration(eventId),
onSuccess: () => {
toast.success('申し込みをキャンセルしました');
queryClient.invalidateQueries(['events']);
queryClient.invalidateQueries(['user-registrations']);
},
});
ユーザーストーリー
申し込みフロー
- 未認証ユーザー:イベント詳細でログイン促進メッセージ表示
- 認証済みユーザー:「申し込む」ボタン表示
- ボタンクリック → API呼び出し → 成功/エラー表示
- 申し込み済み表示に変更
- 参加者数の更新
キャンセルフロー
- 申し込み履歴ページにアクセス
- キャンセル可能なイベントに「キャンセル」ボタン表示
- ボタンクリック → 確認ダイアログ表示
- 確認 → API呼び出し → 処理完了通知
- 履歴から削除、イベント詳細の参加者数更新
受け入れ基準
- 未認証ユーザーはイベント情報の閲覧のみ可能
- 未認証ユーザーには申し込みボタンの代わりにログイン促進メッセージが表示される
- 認証済みユーザーのみがイベントに申し込むことができる
- 定員に達したイベントには申し込めない
- 同一ユーザーによる重複申し込みは防止される
- 認証済みユーザーは申し込み済みイベントをキャンセルできる
- イベント開始後のキャンセルは不可
- 認証済みユーザーは自分の申し込み履歴を一覧で確認できる
- ユーザーIDが申し込み情報に正しく紐付けられている
- 申し込み・キャンセル時に定員数が正確に更新される
- エラーケースで適切なエラーメッセージが表示される
テスト計画
-
正常系テスト
- 申し込み → キャンセルの一連フロー
- 定員管理の動作確認
- 申し込み履歴の正確性
-
異常系テスト
- 未認証でのアクセス
- 重複申し込み試行
- 満員イベントへの申し込み
- 他人のイベントキャンセル試行
- イベント開始後のキャンセル試行
-
UI/UXテスト
- レスポンシブ対応
- ローディング状態
- エラー状態表示
- 楽観的更新の動作
見積もり
- 実装時間: 10-14日
- テスト時間: 2-3日
- 合計: 12-17日
ブランチ
feature/issue-5-event-registration-cancel
備考
- メール送信機能は Issue メール通知システムの実装 #28 で実装予定
- この Issue 完了後、基本的なイベント参加機能が利用可能
- Issue メール通知システムの実装 #28 完了後、完全なユーザー体験が提供される
Metadata
Metadata
Assignees
Labels
blocked他の機能の実装完了後まで他の機能の実装完了後までblocking他の Issue をブロック中他の Issue をブロック中feature新機能の追加新機能の追加priority: medium中優先度中優先度