ねらいCONFIRMED からキャンセルできるよう遷移ルールを直し、自分の画面から実際に通します。
さわるファイル| 書く | src/main/java/com/example/order/service/OrderServiceImpl.javaCONFIRMED の遷移を直す |
| 書く | src/main/resources/static/dashboard.htmlステータス変更ボタンを足す |
手順1
考える
case Order.STATUS_CONFIRMED に CANCELLED を足すとき、いまある SHIPPED への遷移をどう残すかを先に決めます。
2
書く
claude で validateStatusTransition の case Order.STATUS_CONFIRMED を対象に指定し、CANCELLED への遷移も許可するよう依頼します。SHIPPED は今までどおり残すと添えます。
3
書く
@src/main/resources/static/dashboard.html を対象に「行から PATCH /api/orders/{id}/status を叩いてステータスを変更できるボタンを足してください」と頼みます。叩き先が /cancel ではなく /status であることを、必ず言葉で指定します。
4
答え合わせ
Java を直したので、1枚目のターミナルで Ctrl+C を押し、.\mvnw.cmd spring-boot:run で起動し直します。画面のボタンから id=2 を CANCELLED にし、続けて id=3 と id=4 でも試します。
できたら- 画面のボタンから id=2 を CANCELLED にでき、再読み込みすると一覧の id=2 が CANCELLED で表示される
- CONFIRMED の id=3 を SHIPPED に変える操作は、今までどおり通る
- SHIPPED の id=4 を CANCELLED にしようとすると通らない(共通エラーハンドラが無いので 500 で返る)
考えることInvalidOrderStateException は業務エラーなのに 500 で返る。本来はどの HTTP ステータスが正しいか。
AI の出方文字列の "CANCELLED" を直に埋め込む案が出ます。Order.STATUS_CANCELLED の定数に直っているかを変更内容で確かめてください。case ブロックごと書き換えて SHIPPED への遷移を消してしまう案も出るので、そこも見ます。画面側では PATCH /api/orders/{id}/cancel を叩くボタンが出ることがあります。cancelOrder は遷移ルールを通らず、直す前でも 200 を返してしまうので、fetch のパスが /status になっているかを確かめてください。
D1-5+@RestControllerAdvice の共通エラーハンドラを足し、OrderNotFoundException を 404、InvalidOrderStateException を 400 に対応づけてください。実装後に1枚目のターミナルで Ctrl+C を押し、.\mvnw.cmd spring-boot:run で起動し直してから SHIPPED の受注を叩くと、500 だったものが 400 に変わります。余力があれば updateOrder と deleteOrder に、PENDING 以外を弾くステータスチェックも足してみてください。
くわしく(背景・詰まったときの対処)
OrderServiceImpl の validateStatusTransition は、受注ステータスをある値から別の値へ変えてよいかを判定するメソッドです。配布時点では case Order.STATUS_CONFIRMED が SHIPPED への遷移しか許していないため、確定済みの受注をキャンセルできません。業務ルールでは PENDING と CONFIRMED からのキャンセルを認めます。出荷済み以降は認めません。モノが動いたのに帳簿だけ消える状態になるためです。
確認は PATCH /api/orders/{id}/status で行います。内部で validateStatusTransition が呼ばれるからです。PATCH /api/orders/{id}/cancel は cancelOrder という別のメソッドを呼ぶので、遷移ルールの確認には使いません。手順3で作るボタンも、押したときに叩くのは /status のほうです。
ステータス値は文字列の直書きではなく Order の定数を使います。綴り間違いをコンパイルの時点で見つけられるからです。
画面のボタンがうまく動かないときは、ターミナルから直接叩いても確かめられます。PowerShell なら Invoke-RestMethod -Method Patch -Uri http://localhost:8080/api/orders/2/status -ContentType "application/json" -Body (@{status="CANCELLED"} | ConvertTo-Json) の1行です。返ってきた status が CANCELLED になっていれば通っています。
配布データでは id=2 と id=3 が CONFIRMED、id=4 が SHIPPED で入っています。id=2 を一度 CANCELLED にすると遷移元が変わるので、やり直すときはアプリを起動し直してください。H2 はメモリ上で動くので、起動のたびに配布時の10件へ戻ります。
新しいファイルは作りません。編集は OrderServiceImpl.java の中と、自分のダッシュボードだけです。手順4で起動し直すのは OrderServiceImpl を直したためで、ボタンを足した HTML のほうは再読み込みだけで反映されます。ボタンの見た目や文言をあとから直すときは、起動したまま再読み込みで確かめてください。