103 lines
3.5 KiB
C#
103 lines
3.5 KiB
C#
using Socialize.Infrastructure.Security;
|
|
using Socialize.Modules.Notifications.Contracts;
|
|
|
|
namespace Socialize.Modules.Assets.Handlers;
|
|
|
|
public record CreateAssetRevisionRequest(
|
|
string SourceReference,
|
|
string? PreviewUrl,
|
|
string? Notes);
|
|
|
|
public class CreateAssetRevisionRequestValidator
|
|
: Validator<CreateAssetRevisionRequest>
|
|
{
|
|
public CreateAssetRevisionRequestValidator()
|
|
{
|
|
RuleFor(x => x.SourceReference).NotEmpty().MaximumLength(2048);
|
|
RuleFor(x => x.PreviewUrl).MaximumLength(2048);
|
|
RuleFor(x => x.Notes).MaximumLength(1024);
|
|
}
|
|
}
|
|
|
|
public class CreateAssetRevisionHandler(
|
|
AppDbContext dbContext,
|
|
AccessScopeService accessScopeService,
|
|
INotificationEventWriter notificationEventWriter)
|
|
: Endpoint<CreateAssetRevisionRequest, AssetRevisionDto>
|
|
{
|
|
public override void Configure()
|
|
{
|
|
Post("/api/assets/{id}/revisions");
|
|
Options(o => o.WithTags("Assets"));
|
|
}
|
|
|
|
public override async Task HandleAsync(CreateAssetRevisionRequest request, CancellationToken ct)
|
|
{
|
|
Guid id = Route<Guid>("id");
|
|
|
|
Asset? asset = await dbContext.Assets.SingleOrDefaultAsync(candidate => candidate.Id == id, ct);
|
|
if (asset is null)
|
|
{
|
|
await SendNotFoundAsync(ct);
|
|
return;
|
|
}
|
|
|
|
ContentItem? contentItem = await dbContext.ContentItems
|
|
.SingleOrDefaultAsync(candidate => candidate.Id == asset.ContentItemId, ct);
|
|
|
|
if (contentItem is not null &&
|
|
!accessScopeService.CanContributeToProject(User, contentItem.WorkspaceId, contentItem.ClientId, contentItem.ProjectId))
|
|
{
|
|
await SendForbiddenAsync(ct);
|
|
return;
|
|
}
|
|
|
|
int revisionNumber = asset.CurrentRevisionNumber + 1;
|
|
asset.CurrentRevisionNumber = revisionNumber;
|
|
asset.PreviewUrl = string.IsNullOrWhiteSpace(request.PreviewUrl) ? asset.PreviewUrl : request.PreviewUrl.Trim();
|
|
|
|
AssetRevision revision = new()
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
AssetId = asset.Id,
|
|
RevisionNumber = revisionNumber,
|
|
SourceReference = request.SourceReference.Trim(),
|
|
PreviewUrl = string.IsNullOrWhiteSpace(request.PreviewUrl) ? null : request.PreviewUrl.Trim(),
|
|
Notes = string.IsNullOrWhiteSpace(request.Notes) ? null : request.Notes.Trim(),
|
|
CreatedByUserId = User.GetUserId(),
|
|
CreatedAt = DateTimeOffset.UtcNow,
|
|
};
|
|
|
|
dbContext.AssetRevisions.Add(revision);
|
|
await dbContext.SaveChangesAsync(ct);
|
|
|
|
if (contentItem is not null)
|
|
{
|
|
await notificationEventWriter.WriteAsync(
|
|
new NotificationEventWriteModel(
|
|
asset.WorkspaceId,
|
|
asset.ContentItemId,
|
|
"asset.revision.created",
|
|
"AssetRevision",
|
|
revision.Id,
|
|
$"A new asset revision was added to {asset.DisplayName}.",
|
|
User.GetUserId(),
|
|
User.GetEmail(),
|
|
$$"""{"revisionNumber":"{{revisionNumber}}"}"""),
|
|
ct);
|
|
}
|
|
|
|
AssetRevisionDto dto = new(
|
|
revision.Id,
|
|
revision.AssetId,
|
|
revision.RevisionNumber,
|
|
revision.SourceReference,
|
|
revision.PreviewUrl,
|
|
revision.Notes,
|
|
revision.CreatedByUserId,
|
|
revision.CreatedAt);
|
|
|
|
await SendAsync(dto, StatusCodes.Status201Created, ct);
|
|
}
|
|
}
|