Merge branch 'master' into worktree-mosaic-library

Renumbers the mosaic's requirement IDs out of the way of the download work
that landed on master in parallel: it had already claimed DR-163/DR-164 and
UT-162, so the mosaic layout is now DR-172, the library favourites scope
DR-173, and its composition test UT-167.

Note for the download branch: its UT-162..UT-165 rows trace to DR-163..DR-166,
none of which are defined in requirements.md — that branch defined DR-167..171
instead. Those references are orphaned and want a look; nothing here touches
them.
This commit is contained in:
2026-08-16 00:04:26 +02:00
26 changed files with 2495 additions and 1554 deletions
+22 -3
View File
@@ -870,13 +870,32 @@ async getDownloads(userId: string, statusFilter: string[] | null) : Promise<Down
return await TAURI_INVOKE("get_downloads", { userId, statusFilter });
},
/**
* Pause a download
* Pause a download.
*
* Writing `status = 'paused'` is only half of it, and used to be all of it: the
* streaming task knew nothing about the row and kept running, then overwrote it
* with `completed`/`failed` when it finished. The row flicked to "paused" and
* undid itself — the reported "pause does not work". Signalling the worker is
* what actually stops the bytes; it leaves the `.part` file in place so
* [`resume_download`] can continue from it.
*
* A queued (not yet started) download has no worker to signal, and the status
* write alone is enough — the pump skips anything that is not `pending`.
*
* TRACES: UR-055 | DR-168
*/
async pauseDownload(downloadId: number) : Promise<null> {
return await TAURI_INVOKE("pause_download", { downloadId });
},
/**
* Resume a paused download
* Resume a paused download.
*
* Flipping the row back to `pending` is likewise not enough on its own: the
* pump is not a poller, it runs when something calls it, so a resumed download
* sat untouched until some unrelated event happened to pump the queue. That is
* the other half of "resume does not work".
*
* TRACES: UR-055 | DR-168
*/
async resumeDownload(downloadId: number) : Promise<null> {
return await TAURI_INVOKE("resume_download", { downloadId });
@@ -2063,7 +2082,7 @@ export type Library = { id: string; name: string; collectionType: string; imageT
* collection-type → category table any more than an item-type one. See
* `SearchScope::for_collection_type`.
*
* TRACES: UR-075 | DR-164
* TRACES: UR-075 | DR-173
*/
favoritesScope?: SearchScope | null }
/**