mirror of
https://github.com/nestriness/nestri.git
synced 2026-11-03 22:22:39 +02:00
Until now every finished run said only `ended` or `failed`. A user stop, a trial window running out, an idle timeout, a host restart and a game quitting were indistinguishable afterwards. **Schema.** Migration `0026_session_end_reason` adds two nullable columns to `session`: - `end_reason`: one of `user`, `window`, `hours`, `idle`, `left_queue`, `game_exited`, `launch_failed`, `host_stopped`, `host_restart`. - `time_claimed`: when a host took the run, set on `requested → starting`. **API.** - `POST /session/:id/state` takes an optional `endReason`. With `ended` or `failed` it is stored. With `starting` or `live` it is a 400 and the run does not move. - Leaving it out of a terminal report stores null, so host agents that predate this keep working. - `endReason` and `timeClaimed` are returned on every session response. - The API writes the reasons it decides itself: `user` when a run nobody has claimed is stopped, and `left_queue` when a waiting run is abandoned (the `Left the queue` message is kept). **New transition, `starting → ended`.** A run stopped while its game is still downloading has failed at nothing, and never reached `live`, which is where billing starts. Until now the only way out of `starting` was `failed`. **Release order: this goes first.** The host agent that sends `endReason` is a separate change. This route's body schema is strict, so without this deployed the current API answers that agent with a 400. **Tests.** - API: 185 pass, 5 of them new. - Core: 41 session tests pass, 3 of them new. - The new tests fail when the implementation is broken on purpose. - No new type errors.