fix: résoudre series_id dans torrent_downloads via JOIN

La table torrent_downloads ne stockait pas series_id. Le DTO l'exposait
comme optional mais était toujours null, causant des liens KO en page
downloads (fallback sur series_name alors que la route attend un UUID).

Ajout d'un LEFT JOIN series sur (library_id, LOWER(name)) dans la query
list_torrent_downloads pour résoudre le series_id dynamiquement.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-30 09:27:41 +02:00
parent 6511ed02cb
commit c5ada110ab

View File

@@ -28,6 +28,7 @@ pub struct TorrentNotifyRequest {
pub struct TorrentDownloadDto { pub struct TorrentDownloadDto {
pub id: String, pub id: String,
pub library_id: String, pub library_id: String,
pub series_id: Option<String>,
pub series_name: String, pub series_name: String,
pub expected_volumes: Vec<i32>, pub expected_volumes: Vec<i32>,
pub qb_hash: Option<String>, pub qb_hash: Option<String>,
@@ -104,9 +105,12 @@ pub async fn list_torrent_downloads(
State(state): State<AppState>, State(state): State<AppState>,
) -> Result<Json<Vec<TorrentDownloadDto>>, ApiError> { ) -> Result<Json<Vec<TorrentDownloadDto>>, ApiError> {
let rows = sqlx::query( let rows = sqlx::query(
"SELECT id, library_id, series_name, expected_volumes, qb_hash, content_path, \ "SELECT td.id, td.library_id, td.series_name, td.expected_volumes, td.qb_hash, td.content_path, \
status, imported_files, error_message, progress, download_speed, eta, created_at, updated_at \ td.status, td.imported_files, td.error_message, td.progress, td.download_speed, td.eta, \
FROM torrent_downloads ORDER BY created_at DESC LIMIT 100", td.created_at, td.updated_at, s.id AS series_id \
FROM torrent_downloads td \
LEFT JOIN series s ON s.library_id = td.library_id AND LOWER(s.name) = LOWER(td.series_name) \
ORDER BY td.created_at DESC LIMIT 100",
) )
.fetch_all(&state.pool) .fetch_all(&state.pool)
.await?; .await?;
@@ -116,12 +120,14 @@ pub async fn list_torrent_downloads(
.map(|row| { .map(|row| {
let id: Uuid = row.get("id"); let id: Uuid = row.get("id");
let library_id: Uuid = row.get("library_id"); let library_id: Uuid = row.get("library_id");
let series_id: Option<Uuid> = row.get("series_id");
let expected_volumes: Vec<i32> = row.get("expected_volumes"); let expected_volumes: Vec<i32> = row.get("expected_volumes");
let created_at: DateTime<Utc> = row.get("created_at"); let created_at: DateTime<Utc> = row.get("created_at");
let updated_at: DateTime<Utc> = row.get("updated_at"); let updated_at: DateTime<Utc> = row.get("updated_at");
TorrentDownloadDto { TorrentDownloadDto {
id: id.to_string(), id: id.to_string(),
library_id: library_id.to_string(), library_id: library_id.to_string(),
series_id: series_id.map(|u| u.to_string()),
series_name: row.get("series_name"), series_name: row.get("series_name"),
expected_volumes, expected_volumes,
qb_hash: row.get("qb_hash"), qb_hash: row.get("qb_hash"),