SlotKeeper 設計と品質

create_reservation sequence

sequenceDiagram
  autonumber
  participant User as User
  participant API as API
  participant DB as DB
  User->>API: POST /reservations
  alt Authorization ヘッダのBearer tokenが未指定、または署名・issuer・client・用途・期限を検証できない場合。
    API-->>User: HTTP 401 Unauthorized<br/>authentication_required / invalid_token
  end
  alt Path/Query/Header/Body が型または制約に一致しない場合。
    API-->>User: HTTP 422 Unprocessable Content<br/>invalid_input
  end
  Note over API,DB: DBの直列化競合・一意性競合・OCC競合は、rollback後に新しいsnapshotで処理順を最大12回・8秒まで再実行する。再送安全な処理のため、成否不明の接続断も再実行する。
  Note over API,DB: DB transaction範囲開始 (最初のDB操作からcommit/rollbackまで)
  API->>DB: 利用者とIdempotency-Keyに対応する予約作成要求の成功記録を取得する。<br/>SQL 001_select_idempotency_records.sql<br/>テーブル idempotency_records
  alt 有効期限内の成功記録がIdempotency-Keyに紐づいている場合。
    alt 成功記録の正規化入力と再送された要求が一致しない場合。
      API->>API: 同じIdempotency-Keyで異なる入力が送られた場合の運用ログと error response を組み立てる。
      API->>DB: DB transactionをrollbackして変更を破棄する。
      API-->>User: HTTP 409 Conflict<br/>idempotency_input_mismatch
    end
    API->>API: 成功記録に保存した元の作成応答を組み立てる。
    API-->>User: HTTP 201 Created
  end
  API->>API: 新規要求の開始時刻・長さ・15分刻み・日本時間の日付を検証する。
  API->>DB: 同一資源の予約作成・取消・無効化を競合させるため、内部制御版を進めて資源を取得する。<br/>SQL 002_update_resources_control_version.sql<br/>テーブル resources
  alt 予約対象の資源が存在しない場合。
    API->>DB: DB transactionをrollbackして変更を破棄する。
    API-->>User: HTTP 404 Not Found<br/>resource_not_found
  end
  alt 予約対象の資源が有効でない場合。
    API->>API: 無効な資源への予約を拒否する場合の運用ログと error response を組み立てる。
    API->>DB: DB transactionをrollbackして変更を破棄する。
    API-->>User: HTTP 409 Conflict<br/>resource_inactive
  end
  API->>DB: 取消済みを除き、半開区間が重なる確定予約があるかを判定する。<br/>SQL 003_select_reservations.sql<br/>テーブル reservations
  alt 取消済みを除き、半開区間が重なる確定予約がある場合。
    API->>API: 予約枠が重なる場合の運用ログと error response を組み立てる。
    API->>DB: DB transactionをrollbackして変更を破棄する。
    API-->>User: HTTP 409 Conflict<br/>slot_taken
  end
  API->>DB: 有効期限を過ぎた成功記録を新規要求として扱うため削除する。<br/>SQL 004_delete_idempotency_records.sql<br/>テーブル idempotency_records
  API->>DB: 初めて予約する利用者を記録する。<br/>SQL 005_insert_users.sql<br/>テーブル users
  API->>DB: 予約を確定状態の初期版で保存する。<br/>SQL 006_insert_reservations.sql<br/>テーブル reservations
  alt 予約の保存結果を取得できない場合。
    API->>DB: DB transactionをrollbackして変更を破棄する。
    API-->>User: HTTP 500 Internal Server Error<br/>reservation_not_saved
  end
  API->>DB: 予約作成の履歴を予約と同じtransactionで追記する。<br/>SQL 007_insert_reservation_events.sql<br/>テーブル reservation_events
  API->>DB: 元の成功応答を予約と同じtransactionで24時間の成功記録として保存する。<br/>SQL 008_insert_idempotency_records.sql<br/>テーブル idempotency_records
  API->>DB: DB transactionをcommitして変更を確定する。
  API->>API: 作成した予約のレスポンスを組み立てる。
  API-->>User: HTTP 201 Created
  alt Router で捕捉した例外を error response に変換する場合。
    API->>API: Router で捕捉した例外を運用ログと HTTP error response に変換する。
    API-->>User: HTTP 500 Internal Server Error<br/>internal server error
  end
  alt DBの競合や接続障害が再試行上限を超えた場合。
    API-->>User: HTTP 503 Service Unavailable<br/>storage_temporarily_unavailable
  end