| | | 1 | | using Enjoy.Domain.Shared.Errors; |
| | | 2 | | using Enjoy.Domain.Shared.Extensions; |
| | | 3 | | using Enjoy.Domain.Shared.Messaging; |
| | | 4 | | using Enjoy.Domain.Shared.Primitives; |
| | | 5 | | using Enjoy.Domain.Shared.Results; |
| | | 6 | | using Enjoy.Domain.Jokes.Events; |
| | | 7 | | using Enjoy.Domain.Jokes.ValueObjects; |
| | | 8 | | |
| | | 9 | | namespace Enjoy.Domain.Jokes.Entities; |
| | | 10 | | |
| | | 11 | | public sealed class Joke : AggregateRoot, IAuditableEntity |
| | | 12 | | { |
| | 28 | 13 | | public static string NewId() => $"joke_{Guid.CreateVersion7()}"; |
| | | 14 | | |
| | 35 | 15 | | public JokeText Text { get; private set; } |
| | 53 | 16 | | public string AuthorId { get; private set; } |
| | 27 | 17 | | public Origin Origin { get; private set; } |
| | | 18 | | |
| | 3 | 19 | | public DateTime CreatedOnUtc { get; set; } |
| | 3 | 20 | | public DateTime? ModifiedOnUtc { get; set; } |
| | | 21 | | |
| | 26 | 22 | | private readonly List<string> _topicIds = []; |
| | 12 | 23 | | public IReadOnlyCollection<string> TopicIds => _topicIds.AsReadOnly(); |
| | | 24 | | |
| | 1 | 25 | | private Joke() : base() |
| | 1 | 26 | | { |
| | 1 | 27 | | AuthorId = null!; |
| | 1 | 28 | | Text = default; |
| | 1 | 29 | | Origin = default; |
| | 1 | 30 | | } |
| | | 31 | | |
| | 25 | 32 | | private Joke(string id, JokeText text, string authorId, Origin origin) : base(id) |
| | 25 | 33 | | { |
| | 25 | 34 | | Text = text; |
| | 25 | 35 | | AuthorId = authorId; |
| | 25 | 36 | | Origin = origin; |
| | 25 | 37 | | } |
| | | 38 | | |
| | | 39 | | public static Result<Joke> Create(string text, string authorId, string origin) |
| | 31 | 40 | | { |
| | 31 | 41 | | List<Error> errors = []; |
| | | 42 | | |
| | 31 | 43 | | if (string.IsNullOrWhiteSpace(authorId)) |
| | 4 | 44 | | errors.Add(Error.Joke.AuthorRequired); |
| | | 45 | | |
| | 31 | 46 | | var textResult = JokeText.Create(text); |
| | 31 | 47 | | if (textResult.IsFailure) |
| | 2 | 48 | | errors.AddRange(textResult.Errors); |
| | | 49 | | |
| | 31 | 50 | | var originResult = Origin.Create(origin); |
| | 31 | 51 | | if (originResult.IsFailure) |
| | 2 | 52 | | errors.AddRange(originResult.Errors); |
| | | 53 | | |
| | 31 | 54 | | if (!errors.IsEmpty()) |
| | 6 | 55 | | return Result<Joke>.Failure(errors); |
| | | 56 | | |
| | 25 | 57 | | Joke joke = new( |
| | 25 | 58 | | NewId(), |
| | 25 | 59 | | textResult.Value, |
| | 25 | 60 | | authorId.Trim(), |
| | 25 | 61 | | originResult.Value); |
| | 25 | 62 | | joke.RaiseDomainEvent(new JokeCreatedDomainEvent(DomainEvent.NewId(), joke.Id, joke.AuthorId)); |
| | 25 | 63 | | return Result<Joke>.Success(joke); |
| | 31 | 64 | | } |
| | | 65 | | |
| | | 66 | | public Result UpdateText(string text) |
| | 5 | 67 | | { |
| | 5 | 68 | | var textResult = JokeText.Create(text); |
| | 5 | 69 | | if (textResult.IsFailure) |
| | 2 | 70 | | return Result.Failure(textResult.Errors); |
| | 3 | 71 | | if (Text.Value == textResult.Value.Value) |
| | 1 | 72 | | return Result.Success(); |
| | | 73 | | |
| | 2 | 74 | | Text = textResult.Value; |
| | 2 | 75 | | RaiseDomainEvent(new JokeTextUpdatedDomainEvent(DomainEvent.NewId(), Id)); |
| | 2 | 76 | | return Result.Success(); |
| | 5 | 77 | | } |
| | | 78 | | |
| | | 79 | | public Result AddTopic(string topicId) |
| | 18 | 80 | | { |
| | 18 | 81 | | if (string.IsNullOrWhiteSpace(topicId)) |
| | 3 | 82 | | return Result.Failure(Error.Joke.TopicIdRequired); |
| | 15 | 83 | | if (_topicIds.Contains(topicId)) |
| | 1 | 84 | | return Result.Success(); |
| | | 85 | | |
| | 14 | 86 | | _topicIds.Add(topicId); |
| | 14 | 87 | | return Result.Success(); |
| | 18 | 88 | | } |
| | | 89 | | |
| | | 90 | | public Result RemoveTopic(string topicId) |
| | 5 | 91 | | { |
| | 5 | 92 | | if (string.IsNullOrWhiteSpace(topicId)) |
| | 3 | 93 | | return Result.Success(); |
| | | 94 | | |
| | 2 | 95 | | _topicIds.Remove(topicId); |
| | 2 | 96 | | return Result.Success(); |
| | 5 | 97 | | } |
| | | 98 | | } |