Idempotent on (ViewerId, BattleId); evicts oldest CreateTime row when
at cap. No-op when ctx is null (server-restart safety).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bridges the start-time -> finish-time gap. /finish carries neither
battle_id nor opponent identity; this store holds both for the finish
handler to compose a ViewerBattleHistory row.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>