ScriptAssistant

Records the one presenter a Slideshow user chose - character, placement and voice.

PUT and not PATCH: the whole choice replaces the previous one, the same way UpdateOutlineScene replaces a scene's editable state. 404 also covers "this session is not a slideshow session you may write a presenter to" only in the sense that the FEATURE is off - a Context session that exists answers 422, because refusing it explicitly is the point (see SetSlideshowPresenter's mode guard).

422 also covers the write the STORE refused - the session was deleted, or stopped being a Slideshow, between the handler's read and the patch. One status for both because the repository reports one bool for both, and 404 would be a claim about which.

GATED ON DeckToSlideshow AT THE ENDPOINT. The controller used to carry a class-level ScriptAssistant gate as well (removed once that flag was fully rolled out); UnleashFeatureGateFilter requires ALL gates on an endpoint to pass, so stacking a controller gate back on top stays safe. Pinned by UnleashFeatureGateFilterTests.

It has to be here and not only in the handler. An action filter short-circuits before the action body runs, so it precedes MediatR entirely; the handler's check runs INSIDE the pipeline, after ValidatorBehavior has already rejected a malformed body with a 422 and run the validator's tenant and character lookups. With the flag off this endpoint must not exist, and "does not exist" cannot be something a caller discovers only after passing validation. The handler keeps its own check all the same - it is the backstop for any non-HTTP caller of the command, and the only one a handler unit test can see.

put/api/script-assistant/sessions/{sessionId}/presenter

Request

  • Base URL
    https://api.wearelearning.io (the document declares no server; this is the origin it was published from)
  • Auth
    OAuth 2
    Implicit: https://login.wearelearning.io/authorize?audience=https://api.wearelearning.io

Path parameters

sessionIdstring required

Request body

characterIdstring required
rotationnumber float nullable

Required, and nullable here for the same reason WeAreLearning.R2D2.Api.DTO.ScriptAssistant.SetSlideshowPresenterRequestDto.Position is. As a plain float an omitted rotation bound to 0f and was written as a real 0-degree rotation, so a malformed or stale client silently reoriented the presenter. Absent and zero have to be different answers; the validator refuses the first and accepts the second. Must be in [0, 360) - out of range is refused, not wrapped.

voiceNamestring nullable

Omit entirely for "no voice chosen". An empty string is not the same answer and is refused, and so is any name the voice catalogue does not know - see the validator for why existence is checked here while locale fitness is not.

Matched case-insensitively, and STORED in the catalogue's own spelling - the response echoes back what was persisted, which may differ in case from what was sent.

Response

OK

characterIdstring required
rotationnumber float required

Degrees, positive clockwise. Always in [0, 360).

voiceNamestring nullable

Null means no voice was chosen, which is a legal answer - it is resolved from the character's gender, the story language and the tenant's defaults when the story is built. It is NOT the same as an empty string, which the write refuses.

Changes

No recorded changes to this operation across all 1 revision of this API.