Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

セッションライフサイクル

この文書は、セッション管理の実装を クライアント側とサーバー側に分けて説明します。

1. 管理責務の分離

管理面主な保存先主な責務
クライアントlocalStorage (starkBallotSession)画面遷移フェーズ、クライアント TTL、UI 復元
サーバーVoteStore 実装(Mock/File/Amplify)投票データ、掲示板、集計結果、検証結果

クライアントとサーバーは X-Session-ID で紐づきます(ただし全エンドポイントで必須ではありません)。

2. クライアント側フェーズ

クライアントセッション(src/lib/session/client.ts)のフェーズは以下の 3 つです。

  • voting
  • finalizing
  • verifying

主な遷移トリガー:

  • POST /api/session 後に generateSessionId(...)voting 開始
  • aggregate 画面で非同期集計の pending/running を検知すると saveSessionData({ phase: 'finalizing' })
  • 集計結果を保存すると saveSessionData({ finalizeResult, phase: 'verifying' })

3. クライアント TTL 実装

SESSION_PHASE_TIMEOUTS_MS:

  • voting: 30 分
  • finalizing: 30 分
  • verifying: 24 時間

TTL 更新の実装ポイント:

  • generateSessionId(...): 新規作成
  • saveSessionData(...): フェーズを加味して expiresAt を再計算
  • updateLastActivity(...): 現在フェーズで expiresAt を再延長

期限切れ判定:

  • checkTimeout() または getSessionData() が有効期限超過を検出すると clearSession() を実行

補足:

  • 専用 heartbeat API はありません。
  • 60 秒間隔の updateLastActivity() は現行実装では verify 画面で実行されています。

4. サーバー側セッション状態

サーバーは SessionData に以下を保持します。

  • 投票(votes, userVoteIndex, botCount
  • 集計状態(finalizationState
  • 集計結果(finalizationResult
  • 最終活動時刻(lastActivity

finalizationState.status は以下を取り得ます。

  • pending
  • running
  • succeeded
  • failed
  • timeout

5. サーバー側 TTL / 失効の実装差分

サーバー側の失効挙動はストア実装で異なります。

ストア失効/TTL の実装
MockSessionStoregetActiveSessionCount() 呼び出し時に lastActivity から 5 分超を掃除
FileMockSessionStoregetActiveSessionCount() 呼び出し時に同様に 5 分超を掃除
AmplifySessionStoreTTL 属性を保存。初期は AMPLIFY_DATA_TTL_SECONDS(既定 1800 秒)、finalized 更新時は AMPLIFY_DATA_VERIFICATION_TTL_SECONDS(既定 86400 秒)を使用

重要事項:

  • 「同時セッション上限 100」を強制するロジックは、現行の /api/session 実装には入っていません。

6. X-Session-ID スコープ

X-Session-ID の要否はエンドポイントごとに異なります。

ヘッダー必須の代表例:

  • /api/vote, /api/progress, /api/finalize, /api/finalize/cancel
  • /api/verify, /api/verification/run
  • /api/bulletin, /api/bulletin/:voteId, /api/bulletin/:voteId/proof, /api/bulletin/consistency-proof
  • /api/botdata/:id, /api/sth

ヘッダー不要の代表例:

  • /api/sessions/:sessionId/status(パスパラメータ)
  • /api/verification/bundles/:sessionId/:executionId(パスパラメータ)
  • /api/zkvm-input-hash(クエリ sessionId

実装依存:

  • /api/bitmap-proof(Mock/File は省略可、Amplify は実質必須)

7. マルチタブ時の実務上の注意

localStorage は同一オリジンで共有されるため、タブ間でセッション情報が競合します。

代表的な結果:

  • 片方のタブで投票済み後、別タブで再投票すると ALREADY_VOTED
  • 片方のタブで集計完了後、別タブで再集計すると SESSION_ALREADY_FINALIZED
  • セッション作成を並行すると、最後に保存した starkBallotSession が有効になる