Skip to content

fix(task): /api/tasks/{id}/status を楽観ロック対象外にする(If-Match 撤去)+ ADR-0012 に適用基準を追記 #680

@win2cot

Description

@win2cot

決定(2026-06-19 事故分析で確定)

PATCH /api/tasks/{id}/status楽観ロック(If-Match)対象外とする。現状バックエンドが If-Match を required で要求するが OpenAPI 未定義・フロント未送出のため常に 400。本 Issue で If-Match を撤去して 400 を解消する。

根拠(事故分析)

  • /status単一フィールドの絶対値 SET。ADR-0012 が防ぐ「多フィールド PATCH で他人の未編集列を上書き」型 lost update が構造的に起きない。
  • TaskStatus はステートマシン無しの enum、completedAt は status から決定的に導出され torn state にならない。認可は UseCase が同一トランザクションで再読込して判定 → ロック以外で整合が守られている。
  • version は行単位カウンタのため、付けると無関係なフィールド編集でも status 変更が 412。高頻度操作で誤検知摩擦のみ大きく、正しさの利得はゼロ。
  • status の同時変更は last-write-wins(最後の人間の判断が残る)で自然・低リスク。

判定基準と決定マトリクスは ADR-0012 の amendment に記録する。

やること

  • TaskController.changeStatus から @RequestHeader(IF_MATCH) を撤去
  • ChangeTaskStatusUseCase.execute から ifMatchVersion 引数と version 一致チェック(PreconditionFailedException)を撤去
  • web/js/tasks.js:86 の「If-Match 対象外」コメントと status の 412 ハンドリングを整理(status では 412 を期待しない)
  • OpenAPI /status: If-Match/412 が無いことを確認し、「楽観ロック対象外」を明示記述
  • ADR-0012 を amend: 楽観ロック適用基準を §scope に追記(下記)

ADR-0012 に追記する基準

楽観ロック(If-Match)は「呼び出し側が観測していない変更を上書きしうる write」にのみ適用する。判定軸 = 多フィールドを束ねる write / read-modify-write / 上書きの実害が高いか。単一フィールド絶対値 SET で実害が低く高頻度な endpoint(/status)は対象外。低頻度・高実害な endpoint(/visibility)は付与する(別 Issue)。

受入条件

  • /status が If-Match 無しで 200 を返す(統合 IT)
  • status の同時変更が last-write-wins で破綻しない IT
  • ADR-0012 に適用基準が記載されている

関連

#663(blocks)/ ADR-0012 / /visibility 付与は別 Issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/backendJava / Spring バックエンド実装変更area/docsdocs/ 配下のドキュメント(設計書・規約・ADR 等)変更area/frontendフロントエンド(HTML/CSS/JS/Bootstrap 5)変更area/openapiOpenAPI 仕様(api/openapi.yaml)変更priority/p1High。現スプリント内で完了必須task-type:implコード実装が主体のタスク

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions