55 lines
2.3 KiB
C#
55 lines
2.3 KiB
C#
using LiteCqrs;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using TeleWave.Application.Common.Interfaces;
|
|
using TeleWave.Application.Common.Models;
|
|
using TeleWave.Domain.Media;
|
|
|
|
namespace TeleWave.Application.Media.Register;
|
|
|
|
public sealed class RegisterMediaAssetCommandHandler(IAppDbContext dbContext, IMediaStorage storage)
|
|
: ICommandHandler<RegisterMediaAssetCommand, Result<Guid>>
|
|
{
|
|
public async Task<Result<Guid>> Handle(
|
|
RegisterMediaAssetCommand command,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
// Дедуп по имени: тот же файл уже в библиотеке (кроме проваленных — их разрешаем перезалить).
|
|
var duplicate = await dbContext.MediaAssets.AnyAsync(
|
|
x =>
|
|
x.OriginalFileName == command.OriginalFileName
|
|
&& x.Status != MediaAssetStatus.Failed,
|
|
cancellationToken
|
|
);
|
|
if (duplicate)
|
|
return Result.Failure<Guid>(MediaErrors.DuplicateFileName);
|
|
|
|
var extension = Path.GetExtension(command.OriginalFileName).ToLowerInvariant();
|
|
var asset = MediaAsset.Register(command.OriginalFileName, extension, command.Source);
|
|
|
|
// Сначала фиксируем ассет в БД, затем переносим файл в originals/. Если перенос не удался —
|
|
// откатываем регистрацию, чтобы не оставить orphan (либо есть и строка БД, и файл, либо нет ни
|
|
// того, ни другого). Обратный порядок оставлял бы перемещённый файл без строки БД при сбое save.
|
|
dbContext.MediaAssets.Add(asset);
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
try
|
|
{
|
|
await storage.PromoteToOriginalAsync(
|
|
command.Source,
|
|
command.SourceToken,
|
|
asset.Id,
|
|
extension,
|
|
cancellationToken
|
|
);
|
|
}
|
|
catch
|
|
{
|
|
dbContext.MediaAssets.Remove(asset);
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
throw;
|
|
}
|
|
|
|
return Result.Success(asset.Id);
|
|
}
|
|
}
|