割り勘フェーズ別操作マトリクス設計書

Issue: #174  |  作成日: 2026-04-01  |  対象: the-botch (割り勘アプリ)

1. 概要

割り勘イベントの3つのフェーズ(ENTERING → PAYING → CLOSED)ごとに、許可される操作・ボタン表示・状態変化を明確に定義する。

現状の問題

2. 状態遷移

ENTERING
明細入力
PAYING
送金中
CLOSED
完了

① ENTERING → PAYING(精算開始)

トリガー: 「精算を確定する」ボタン押下

前提条件: 明細が1件以上、参加者が2人以上

処理: 精算結果を計算し、ステータスをPAYINGに変更

② PAYING → ENTERING(明細修正に戻る)

トリガー: 「明細を修正する」ボタン押下

処理: ステータスをENTERINGに戻す。既存の精算結果は削除する

注意: 送金済みのものがある場合は確認ダイアログを表示(後述)

③ PAYING → CLOSED(自動クローズ)

トリガー: 全精算の受領確認が完了したとき自動遷移(既存の動作を維持)

処理: ステータスをCLOSEDに変更

④ CLOSED → 操作不可

CLOSEDになったイベントは閲覧のみ。全操作を無効化する

セレクトボックスの廃止: 現在の自由なステータス変更セレクトボックスを廃止し、上記のボタン操作のみでフェーズ遷移する設計にする。これにより不正な遷移(例: ENTERINGから直接CLOSED)を防止する。

3. フェーズ別操作マトリクス

許可 操作可能 禁止 操作不可(ボタン非表示) 条件付 条件を満たせば操作可能 非表示 UIに表示しない
操作 ENTERING
(明細入力)
PAYING
(送金中)
CLOSED
(完了)
明細(立替)
明細の追加 許可 禁止 フォーム非表示 禁止
明細の編集 許可 禁止 編集ボタン非表示 禁止
明細の削除 許可 禁止 削除ボタン非表示 禁止
参加者
参加者の変更 許可 禁止(既存動作を維持) 禁止
精算
精算を確定する
(ENTERING→PAYING)
条件付
明細1件以上 & 参加者2人以上
非表示 すでにPAYING 非表示
明細を修正する
(PAYING→ENTERING)
非表示 すでにENTERING 許可
送金済みがあれば確認ダイアログ
非表示
送金済みマーク 非表示 精算結果なし 許可
確認ダイアログあり
禁止
受領確認マーク 非表示 条件付
送金済みの精算のみ
禁止
精算結果の表示 非表示 未計算 許可 閲覧のみ 許可 閲覧のみ
イベント全体
イベント名・メモの編集 許可 許可(精算に影響しない項目) 禁止
イベントの削除 許可 確認ダイアログあり 許可 確認ダイアログあり 許可 確認ダイアログあり

4. 送金済みリセットルール

方針: PAYING中に「明細を修正する」で ENTERINGに戻す場合、精算結果ごと削除する。再度「精算を確定する」を押すまで精算結果は表示されない。

理由

明細が変更されると精算金額が変わるため、古い精算結果(送金済みマーク含む)をそのまま残すと矛盾が生じる。精算結果ごとリセットし、再計算後にゼロから送金を行う方がシンプルで安全。

処理フロー

  1. PAYING中に「明細を修正する」ボタンを押す
  2. 送金済みの精算がある場合 → 確認ダイアログ表示(後述)
  3. 確認OK → 既存のSettlementレコードを全削除 + ステータスをENTERINGに変更
  4. 明細の追加・編集・削除が可能になる
  5. 修正完了後に「精算を確定する」で再計算 → PAYINGに遷移

5. 確認ダイアログ

5-1. 送金済みマーク時の確認

送金済みボタンを押した際、誤押下を防ぐために確認ダイアログを表示する。

送金確認

○○さんへの ¥X,XXX の送金を
完了しましたか?

項目内容
タイトル「送金確認」
メッセージ「{送金先の名前}さんへの ¥{金額} の送金を完了しましたか?」
キャンセル何もしない(ダイアログを閉じる)
確定isPaid = true に更新、paidAt に現在時刻を記録

5-2. 明細修正に戻る時の確認(送金済みがある場合)

PAYING中に「明細を修正する」を押した際、すでに送金済みの精算がある場合のみ表示する。

精算結果のリセット

送金済みの精算が X件 あります。
明細を修正すると精算結果がリセットされ、
再度精算をやり直す必要があります。

項目内容
表示条件isPaid = true の Settlement が1件以上存在する場合のみ
メッセージ「送金済みの精算が{N}件あります。明細を修正すると精算結果がリセットされ、再度精算をやり直す必要があります。」
キャンセル何もしない
確定全Settlement削除 → ステータスをENTERINGに変更
送金済みがない場合: 確認ダイアログなしで即座にENTERINGに戻す(精算結果は削除)。

6. UI変更点

6-1. ステータス表示の変更

現状変更後
セレクトボックスで ENTERING / PAYING / CLOSED を自由に選択可能 読み取り専用のバッジ表示に変更。フェーズ遷移は専用ボタンのみ

6-2. フェーズ別のボタン表示

ボタンENTERINGPAYINGCLOSED
「精算を確定する」 表示(条件を満たさない場合はdisabled) 非表示 非表示
「明細を修正する」 非表示 表示 非表示
「送金済み」 非表示 表示(未送金の精算のみ) 非表示
「受領確認」 非表示 表示(送金済み&未受領の精算のみ) 非表示
明細 追加/編集/削除 表示 非表示 非表示
イベント削除 表示 表示 表示

6-3. フェーズ別のセクション表示

セクションENTERINGPAYINGCLOSED
明細一覧 表示(編集可能) 表示(閲覧のみ) 表示(閲覧のみ)
明細追加フォーム 表示 非表示 非表示
精算結果セクション 非表示 表示 表示
精算進捗バー 非表示 表示(X/Y 受領済) 表示(完了表示)

7. API変更点

7-1. 新規エンドポイント

メソッドパス処理
POST /api/warikan/[id]/revert-to-entering PAYING → ENTERING に戻す。全Settlement削除 + ステータス変更をトランザクションで実行

7-2. 既存エンドポイントの変更

エンドポイント変更内容
PUT /api/warikan/[id] リクエストボディからの status 直接変更を禁止する。ステータスは専用エンドポイント経由のみ
POST /api/warikan/[id]/settlements 既存:ステータスがCLOSEDの場合のみ拒否 → 変更:ENTERINGの場合のみ許可(PAYINGで再計算しようとしたら拒否)
POST /api/warikan/[id]/expenses 既存:CLOSEDのみ拒否 → 変更:ENTERINGの場合のみ許可
PUT /api/warikan/[id]/expenses/[expenseId] 同上。ENTERINGの場合のみ許可
DELETE /api/warikan/[id]/expenses/[expenseId] 同上。ENTERINGの場合のみ許可
ステータスチェックの統一: 現状は「CLOSEDなら拒否」という消極的チェックだが、「ENTERINGのみ許可」という積極的チェックに変更する。これにより、将来ステータスが追加されても安全。

8. バリデーション一覧

操作バリデーションエラーメッセージHTTPステータス
精算確定 status !== ENTERING 「明細入力中のイベントのみ精算を確定できます」 400
精算確定 明細が0件 「明細が登録されていません」 400
精算確定 参加者が1人以下 「参加者が2人以上必要です」 400
明細修正に戻る status !== PAYING 「送金中のイベントのみ明細修正に戻れます」 400
明細追加/編集/削除 status !== ENTERING 「明細入力中のイベントのみ編集できます」 400
送金済みマーク status !== PAYING 「送金中のイベントのみ送金済みにできます」 400
受領確認マーク status !== PAYING 「送金中のイベントのみ受領確認できます」 400
受領確認マーク isPaid === false 「送金済みでない精算は受領確認できません」 400
ステータス直接変更 常に拒否 「ステータスは直接変更できません」 400

9. 変更対象ファイル一覧

API(バックエンド)

UI(フロントエンド)

10. データモデル変更

変更なし。 既存のスキーマ(WarikanEvent.status, WarikanSettlement.isPaid/isReceived)で全要件を実現できる。

ステータス遷移表(許可される遷移のみ)
遷移元遷移先トリガー
ENTERINGPAYINGPOST /settlements(精算確定)
PAYINGENTERINGPOST /revert-to-entering(明細修正に戻る)
PAYINGCLOSED全精算の受領確認完了(自動遷移)

— 設計書 終 —