2026-08-09 再試行の失敗を繰り返し記録できるようにする(Issue #20)
- 課題: 実行状態の遷移で
failed -> failedが許可されておらず、オンチェーン操作が2回以上失敗した場合、2回目以降の失敗理由を画面から記録できなかった。#8 / PR #10 でfailedを画面から記録できるようにしたが、複数回失敗するケースには同じ穴が残っていた。Allowlist追加とHENKAKU配布は人手のオンチェーン操作で、失敗と再試行の履歴は誤配布の調査に直結する。 - 決定: Issue #20 の案A(
failed -> failedを許可する)を採る。EXECUTION_TRANSITIONSのfailedに自身を加え、管理画面の失敗記録ボタンの表示条件を完了状態の否定(!== "added"/!== "sent")に揃える。 - 「状態が変わらないのにイベントだけ増える」ことについて: これは欠点ではなく、追記型の監査ログとして正しい。「現在どうなっているか」を持つのが
applicationsの状態列、「何が起きたか」を持つのがapplication_eventsで、2回目の失敗は後者にしか属さない情報のため。 - 案Cを採らなかった理由: 再試行を独立した概念として別途表現する案だが、
application_eventsが既に果たしている役割を二重に持つことになる。MVP-1の段階では重い。 - 案Bを採らなかった理由: 運用ログで補う案は、監査証跡がアプリ外へ分散する。Allowlist追加とHENKAKU配布は監査ログが唯一の裏付けであるため、証跡を1箇所に揃えることを優先した。
- 引き換えに失うもの: この遷移に限り #5 の条件付き更新(compare-and-set)が保護として働かなくなる。遷移前後がどちらも
failedでexpectedStatusが一致するため、二重送信や2人の管理者の同時操作でも両方が成功し、同一内容のイベントが2件残り得る。ローカルDBで実際に2件記録されることを確認した。 - それでも受け入れる理由: 監査ログにとって重複は
created_atで見分けられて後から判断できるが、欠落は復元できない。管理画面には送信中のdisabledがあり、実運用の主因である二重クリックは抑えられる。Runbookにも1回だけ押す旨を明記した。 - 完了状態の保護は維持する:
added -> failedとsent -> failedは引き続き許可しない。承認前(review_status !== 'approved')に実行状態を触れない制約も変わらない。 - 2026-08-08 の記録(
2026-08-08-record-failed-state.md)にあった「failed -> failedは許可しないままとし、複数回の失敗は運用ログへ記録する」という判断は、これで置き換わる。 - 残る論点: 審査側の
needs_info -> needs_infoにも同型のギャップがある(追加情報の依頼を2回目以降記録できない)。同じ判断基準が当てはまるが、審査のやり取りはアプリ外の連絡手段が主であるため、別途扱う。