A .pptx landing in someone's own storage is worth having; a markdown blob is
not, and it is not what they would have downloaded. So this renders through
exactly the path the download uses — stored deck, its figures, the chosen
theme — and PUTs the bytes. The file never travels through the browser.
Offered only when a Nextcloud is connected: an action that always fails is
worse than one that is not offered. An article offers Word, a deck PowerPoint,
and asking for slides from an article is refused with the reason.
Putting a file in Nextcloud now lives in src/utils/nextcloudFiles.js. Two
callers want it and neither should grow its own copy of the WebDAV dance — make
the dated folder a segment at a time, PUT, migrate a legacy plaintext token —
because it reaches into storage that is not ours and a second slightly
different copy is how the two drift. It also replaces a route importing another
route.
Also: a model that leaves the roster now leaves every list that names it.
clinical_assistant.allowed_models and the image roster are advisory copies of
the roster, and a stale id there was invisible until someone asked a clinical
question and the request failed at the gateway. Removing or disabling a model
prunes it; clearing the roster clears them. Re-enabling deliberately does not
re-allow it — that is a separate decision.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU