diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRole.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRole.cs new file mode 100644 index 0000000..446ad2f --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRole.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace WatchIt.Common.Model.Roles; + +public class ActorRole +{ + #region PROPERTIES + + [JsonPropertyName("type_id")] + public required short TypeId { get; set; } + + [JsonPropertyName("name")] + public required string Name { get; set; } + + [JsonPropertyName("media_id")] + public required long MediaId { get; set; } + + [JsonPropertyName("person_id")] + public required long PersonId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaQueryParameters.cs new file mode 100644 index 0000000..aea4560 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleMediaQueryParameters.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; + +namespace WatchIt.Common.Model.Roles; + +public class ActorRoleMediaQueryParameters : ActorRoleQueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "person_id")] + public long? PersonId { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override bool IsMeetingConditions(ActorRoleResponse item) => + ( + base.IsMeetingConditions(item) + && + Test(item.PersonId, PersonId) + ); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonQueryParameters.cs new file mode 100644 index 0000000..b31e24f --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRolePersonQueryParameters.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; + +namespace WatchIt.Common.Model.Roles; + +public class ActorRolePersonQueryParameters : ActorRoleQueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "media_id")] + public long? MediaId { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override bool IsMeetingConditions(ActorRoleResponse item) => + ( + base.IsMeetingConditions(item) + && + Test(item.MediaId, MediaId) + ); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleQueryParameters.cs new file mode 100644 index 0000000..b4a926c --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleQueryParameters.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.Common.Query; + +namespace WatchIt.Common.Model.Roles; + +public abstract class ActorRoleQueryParameters : QueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "type_id")] + public short? TypeId { get; set; } + + [FromQuery(Name = "name")] + public string? Name { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override bool IsMeetingConditions(ActorRoleResponse item) => + ( + Test(item.TypeId, TypeId) + && + TestStringWithRegex(item.Name, Name) + ); + + #endregion + + +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleRequest.cs new file mode 100644 index 0000000..517491c --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleRequest.cs @@ -0,0 +1,24 @@ +using WatchIt.Database.Model.Person; + +namespace WatchIt.Common.Model.Roles; + +public class ActorRoleRequest : ActorRole, IActorRoleMediaRequest, IActorRolePersonRequest +{ + #region PUBLIC METHODS + + PersonActorRole IActorRoleMediaRequest.CreateActorRole(long mediaId) + { + this.MediaId = mediaId; + return CreateActorRole(); + } + + public PersonActorRole CreateActorRole() => new PersonActorRole + { + MediaId = MediaId, + PersonId = PersonId, + PersonActorRoleTypeId = TypeId, + RoleName = Name, + }; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleResponse.cs new file mode 100644 index 0000000..8f6e024 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ActorRoleResponse.cs @@ -0,0 +1,42 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; +using WatchIt.Common.Query; + +namespace WatchIt.Common.Model.Roles; + +public class ActorRoleResponse : ActorRole, IQueryOrderable +{ + #region PROPERTIES + + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "name", item => item.Name }, + { "type_id", item => item.TypeId }, + }; + + + [JsonPropertyName("id")] + public required Guid Id { get; set; } + + #endregion + + + + #region CONSTRUCTORS + + [JsonConstructor] + public ActorRoleResponse() {} + + [SetsRequiredMembers] + public ActorRoleResponse(Database.Model.Person.PersonActorRole data) + { + Id = data.Id; + MediaId = data.MediaId; + PersonId = data.PersonId; + TypeId = data.PersonActorRoleTypeId; + Name = data.RoleName; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRole.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRole.cs new file mode 100644 index 0000000..0eab7d9 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRole.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace WatchIt.Common.Model.Roles; + +public class CreatorRole +{ + #region PROPERTIES + + [JsonPropertyName("type_id")] + public required short TypeId { get; set; } + + [JsonPropertyName("media_id")] + public required long MediaId { get; set; } + + [JsonPropertyName("person_id")] + public required long PersonId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaQueryParameters.cs new file mode 100644 index 0000000..94daf61 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleMediaQueryParameters.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; + +namespace WatchIt.Common.Model.Roles; + +public class CreatorRoleMediaQueryParameters : CreatorRoleQueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "person_id")] + public long? PersonId { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override bool IsMeetingConditions(CreatorRoleResponse item) => + ( + base.IsMeetingConditions(item) + && + Test(item.PersonId, PersonId) + ); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonQueryParameters.cs new file mode 100644 index 0000000..a8604dd --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRolePersonQueryParameters.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc; + +namespace WatchIt.Common.Model.Roles; + +public class CreatorRolePersonQueryParameters : CreatorRoleQueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "media_id")] + public long? MediaId { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override bool IsMeetingConditions(CreatorRoleResponse item) => + ( + base.IsMeetingConditions(item) + && + Test(item.MediaId, MediaId) + ); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleQueryParameters.cs new file mode 100644 index 0000000..8d416f6 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleQueryParameters.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.Common.Query; + +namespace WatchIt.Common.Model.Roles; + +public abstract class CreatorRoleQueryParameters : QueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "type_id")] + public short? TypeId { get; set; } + + #endregion + + + + #region PRIVATE METHODS + + protected override bool IsMeetingConditions(CreatorRoleResponse item) => + ( + Test(item.TypeId, TypeId) + ); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleRequest.cs new file mode 100644 index 0000000..8edba7f --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleRequest.cs @@ -0,0 +1,23 @@ +using WatchIt.Database.Model.Person; + +namespace WatchIt.Common.Model.Roles; + +public class CreatorRoleRequest : CreatorRole, ICreatorRoleMediaRequest, ICreatorRolePersonRequest +{ + #region PUBLIC METHODS + + PersonCreatorRole ICreatorRoleMediaRequest.CreateCreatorRole(long mediaId) + { + this.MediaId = mediaId; + return CreateCreatorRole(); + } + + public PersonCreatorRole CreateCreatorRole() => new PersonCreatorRole + { + MediaId = MediaId, + PersonId = PersonId, + PersonCreatorRoleTypeId = TypeId, + }; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleResponse.cs new file mode 100644 index 0000000..c1b4433 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/CreatorRoleResponse.cs @@ -0,0 +1,40 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; +using WatchIt.Common.Query; + +namespace WatchIt.Common.Model.Roles; + +public class CreatorRoleResponse : CreatorRole, IQueryOrderable +{ + #region PROPERTIES + + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "type_id", item => item.TypeId }, + }; + + + [JsonPropertyName("id")] + public required Guid Id { get; set; } + + #endregion + + + + #region CONSTRUCTORS + + [JsonConstructor] + public CreatorRoleResponse() {} + + [SetsRequiredMembers] + public CreatorRoleResponse(Database.Model.Person.PersonCreatorRole data) + { + Id = data.Id; + MediaId = data.MediaId; + PersonId = data.PersonId; + TypeId = data.PersonCreatorRoleTypeId; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleMediaRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleMediaRequest.cs new file mode 100644 index 0000000..2bf7bf9 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRoleMediaRequest.cs @@ -0,0 +1,28 @@ +using System.Text.Json.Serialization; +using WatchIt.Database.Model.Person; + +namespace WatchIt.Common.Model.Roles; + +public interface IActorRoleMediaRequest +{ + #region PROPERTIES + + [JsonPropertyName("person_id")] + long PersonId { get; set; } + + [JsonPropertyName("type_id")] + short TypeId { get; set; } + + [JsonPropertyName("name")] + string Name { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + PersonActorRole CreateActorRole(long mediaId); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRolePersonRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRolePersonRequest.cs new file mode 100644 index 0000000..cd2be35 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/IActorRolePersonRequest.cs @@ -0,0 +1,19 @@ +using System.Text.Json.Serialization; + +namespace WatchIt.Common.Model.Roles; + +public interface IActorRolePersonRequest +{ + #region PROPERTIES + + [JsonPropertyName("media_id")] + long MediaId { get; set; } + + [JsonPropertyName("type_id")] + short TypeId { get; set; } + + [JsonPropertyName("name")] + string Name { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleMediaRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleMediaRequest.cs new file mode 100644 index 0000000..cc7cc47 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRoleMediaRequest.cs @@ -0,0 +1,25 @@ +using System.Text.Json.Serialization; +using WatchIt.Database.Model.Person; + +namespace WatchIt.Common.Model.Roles; + +public interface ICreatorRoleMediaRequest +{ + #region PROPERTIES + + [JsonPropertyName("person_id")] + long PersonId { get; set; } + + [JsonPropertyName("type_id")] + short TypeId { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + PersonCreatorRole CreateCreatorRole(long mediaId); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRolePersonRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRolePersonRequest.cs new file mode 100644 index 0000000..8181c9c --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Roles/ICreatorRolePersonRequest.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace WatchIt.Common.Model.Roles; + +public interface ICreatorRolePersonRequest +{ + #region PROPERTIES + + [JsonPropertyName("media_id")] + long MediaId { get; set; } + + [JsonPropertyName("type_id")] + short TypeId { get; set; } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs index 0a095e1..ee25ae1 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs @@ -6,6 +6,7 @@ using WatchIt.Common.Model.Genres; using WatchIt.Common.Model.Media; using WatchIt.Common.Model.Photos; using WatchIt.Common.Model.Rating; +using WatchIt.Common.Model.Roles; using WatchIt.WebAPI.Services.Controllers.Media; namespace WatchIt.WebAPI.Controllers; @@ -160,6 +161,40 @@ public class MediaController : ControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task PostPhoto([FromRoute]long id, [FromBody]MediaPhotoRequest body) => await _mediaControllerService.PostMediaPhoto(id, body); + #endregion + + #region Roles + + [HttpGet("{id}/roles/actor")] + [AllowAnonymous] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetMediaAllActorRoles([FromRoute]long id, ActorRoleMediaQueryParameters query) => await _mediaControllerService.GetMediaAllActorRoles(id, query); + + [HttpPost("{id}/roles/actor")] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] + [ProducesResponseType(typeof(ActorRoleResponse), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task PostMediaActorRole([FromRoute]long id, [FromBody]IActorRoleMediaRequest body) => await _mediaControllerService.PostMediaActorRole(id, body); + + [HttpGet("{id}/roles/creator")] + [AllowAnonymous] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetMediaAllCreatorRoles([FromRoute]long id, CreatorRoleMediaQueryParameters query) => await _mediaControllerService.GetMediaAllCreatorRoles(id, query); + + [HttpPost("{id}/roles/creator")] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] + [ProducesResponseType(typeof(CreatorRoleResponse), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task PostMediaCreatorRole([FromRoute]long id, [FromBody]ICreatorRoleMediaRequest body) => await _mediaControllerService.PostMediaCreatorRole(id, body); + #endregion #endregion diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs index a93a938..390a831 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs @@ -1,6 +1,7 @@ using WatchIt.Common.Model.Media; using WatchIt.Common.Model.Photos; using WatchIt.Common.Model.Rating; +using WatchIt.Common.Model.Roles; using WatchIt.WebAPI.Services.Controllers.Common; namespace WatchIt.WebAPI.Services.Controllers.Media; @@ -27,4 +28,9 @@ public interface IMediaControllerService Task GetMediaPhotos(long mediaId, PhotoQueryParameters queryParameters); Task GetMediaPhotoRandomBackground(long mediaId); Task PostMediaPhoto(long mediaId, MediaPhotoRequest data); + + Task GetMediaAllActorRoles(long mediaId, ActorRoleMediaQueryParameters queryParameters); + Task PostMediaActorRole(long mediaId, IActorRoleMediaRequest data); + Task GetMediaAllCreatorRoles(long mediaId, CreatorRoleMediaQueryParameters queryParameters); + Task PostMediaCreatorRole(long mediaId, ICreatorRoleMediaRequest data); } \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs index f8a3f2b..9d34b84 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs @@ -4,8 +4,10 @@ using WatchIt.Common.Model.Genres; using WatchIt.Common.Model.Media; using WatchIt.Common.Model.Photos; using WatchIt.Common.Model.Rating; +using WatchIt.Common.Model.Roles; using WatchIt.Database; using WatchIt.Database.Model.Media; +using WatchIt.Database.Model.Person; using WatchIt.Database.Model.Rating; using WatchIt.Database.Model.ViewCount; using WatchIt.WebAPI.Services.Controllers.Common; @@ -267,7 +269,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS await database.SaveChangesAsync(); - MediaPosterResponse returnData = new MediaPosterResponse(media.MediaPosterImage); + MediaPosterResponse returnData = new MediaPosterResponse(media.MediaPosterImage!); return RequestResult.Ok(returnData); } @@ -351,5 +353,79 @@ public class MediaControllerService(DatabaseContext database, IUserService userS #endregion + #region Roles + + public async Task GetMediaAllActorRoles(long mediaId, ActorRoleMediaQueryParameters queryParameters) + { + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); + if (media is null) + { + return RequestResult.NotFound(); + } + + IEnumerable dataRaw = await database.PersonActorRoles.Where(x => x.MediaId == mediaId).ToListAsync(); + IEnumerable data = dataRaw.Select(x => new ActorRoleResponse(x)); + data = queryParameters.PrepareData(data); + return RequestResult.Ok(data); + } + + public async Task PostMediaActorRole(long mediaId, IActorRoleMediaRequest data) + { + UserValidator validator = userService.GetValidator().MustBeAdmin(); + if (!validator.IsValid) + { + return RequestResult.Forbidden(); + } + + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); + if (media is null) + { + return RequestResult.NotFound(); + } + + PersonActorRole item = data.CreateActorRole(mediaId); + await database.PersonActorRoles.AddAsync(item); + await database.SaveChangesAsync(); + + return RequestResult.Created($"roles/actor/{item.Id}", new ActorRoleResponse(item)); + } + + public async Task GetMediaAllCreatorRoles(long mediaId, CreatorRoleMediaQueryParameters queryParameters) + { + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); + if (media is null) + { + return RequestResult.NotFound(); + } + + IEnumerable dataRaw = await database.PersonCreatorRoles.Where(x => x.MediaId == mediaId).ToListAsync(); + IEnumerable data = dataRaw.Select(x => new CreatorRoleResponse(x)); + data = queryParameters.PrepareData(data); + return RequestResult.Ok(data); + } + + public async Task PostMediaCreatorRole(long mediaId, ICreatorRoleMediaRequest data) + { + UserValidator validator = userService.GetValidator().MustBeAdmin(); + if (!validator.IsValid) + { + return RequestResult.Forbidden(); + } + + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); + if (media is null) + { + return RequestResult.NotFound(); + } + + PersonCreatorRole item = data.CreateCreatorRole(mediaId); + await database.PersonCreatorRoles.AddAsync(item); + await database.SaveChangesAsync(); + + return RequestResult.Created($"roles/creator/{item.Id}", new CreatorRoleResponse(item)); + } + + #endregion + #endregion } \ No newline at end of file