Add metadata management for shows: implement metadata retrieval, application, and updates in the API and UI. Enhance Show and ShowDto models to include metadata fields, and update the database schema accordingly. Introduce new endpoints for metadata operations and integrate metadata display in the ShowDetail component.

This commit is contained in:
Leonid Pershin
2026-07-25 09:07:55 +03:00
parent ba023bc416
commit 0d2dee815e
42 changed files with 2271 additions and 4 deletions
@@ -15,6 +15,18 @@ public class Show
public ShowKind Kind { get; private set; }
public DateTimeOffset CreatedAt { get; private set; }
// ── Метаданные (TMDb/OMDb/вручную) ──
/// <summary>Источник метаданных: «tmdb»/«omdb»/«manual» или null, если не заданы.</summary>
public string? MetadataProvider { get; private set; }
/// <summary>Идентификатор шоу во внешнем источнике (для довыгрузки серий).</summary>
public string? MetadataExternalId { get; private set; }
public int? Year { get; private set; }
/// <summary>Относительный путь локального постера от корня хранилища или null.</summary>
public string? PosterPath { get; private set; }
/// <summary>Серии шоу (backing-field для EF). Порядок показа — по <see cref="ShowEpisode.Position"/>;
/// потребители сортируют явно (см. загрузчик планировщика).</summary>
public IReadOnlyList<ShowEpisode> Episodes => _episodes;
@@ -56,4 +68,44 @@ public class Show
}
public bool CanAddEpisode => Kind != ShowKind.Single || _episodes.Count == 0;
/// <summary>Применить метаданные из внешнего источника. Постер (уже скачанный локально) может быть null.</summary>
public void ApplyMetadata(
string provider,
string externalId,
string? description,
int? year,
string? posterPath
)
{
MetadataProvider = provider;
MetadataExternalId = externalId;
if (!string.IsNullOrWhiteSpace(description))
Description = description;
Year = year;
if (posterPath is not null)
PosterPath = posterPath;
}
/// <summary>Ручная правка метаданных (без внешнего источника).</summary>
public void UpdateMetadataManual(string? description, int? year)
{
MetadataProvider = "manual";
MetadataExternalId = null;
Description = description;
Year = year;
}
/// <summary>Задать/снять локальный постер (после скачивания/загрузки/удаления файла).</summary>
public void SetPosterPath(string? path) => PosterPath = path;
/// <summary>Сбросить все метаданные и постер (файл удаляет вызывающий по старому PosterPath).</summary>
public void ClearMetadata()
{
MetadataProvider = null;
MetadataExternalId = null;
Year = null;
PosterPath = null;
Description = null;
}
}