public async Task <IActionResult> GetPostByIdAsync([FromRoute] int postId)
        {
            var post = await _postRepository.GetPostByIdAsync(postId);

            if (post == null)
            {
                throw new NotFound404Exception("post");
            }

            return(Ok(PostDTO.GetFrom(post)));
        }
        public async Task <IActionResult> UpdatePostAsync([FromRoute] int postId, [FromBody] PostUpdateModel model)
        {
            var post = await _postRepository.GetPostByIdAsync(postId);

            if (post == null)
            {
                throw new NotFound404Exception("post");
            }

            if (string.IsNullOrWhiteSpace(model.Content))
            {
                throw new IsRequiredException("content");
            }

            if (model.Content.Length < 20)
            {
                throw new ContentIsInvalidException();
            }

            if (string.IsNullOrWhiteSpace(model.Title))
            {
                throw new IsRequiredException("title");
            }

            if (await _postRepository.AnyByTitleAsync(model.Title) && !post.Title.Equals(model.Title))
            {
                throw new AlreadyExistsException("title");
            }

            if (model.Title.Length > 100)
            {
                throw new TitleIsInvalidException();
            }

            // bind data
            post.Thumbnail   = model.Thumbnail;
            post.Title       = model.Title;
            post.Author      = model.Author;
            post.Content     = model.Content;
            post.Tags        = model.Tags;
            post.UpdatedDate = DateTime.Now;

            await _postRepository.UpdatePostAsync(post);

            return(Ok(PostDTO.GetFrom(post)));
        }
        public async Task <IActionResult> CreatePostAsync([FromBody] PostCreateModel model)
        {
            if (string.IsNullOrWhiteSpace(model.Content))
            {
                throw new IsRequiredException("content");
            }

            if (model.Content.Length < 20)
            {
                throw new ContentIsInvalidException();
            }

            if (string.IsNullOrWhiteSpace(model.Title))
            {
                throw new IsRequiredException("title");
            }

            if (model.Title.Length > 100)
            {
                throw new TitleIsInvalidException();
            }

            if (await _postRepository.AnyByTitleAsync(model.Title))
            {
                throw new AlreadyExistsException("title");
            }

            DateTime now = DateTime.Now;

            var post = new Post
            {
                AccountId   = CurrentAccountId,
                Thumbnail   = model.Thumbnail,
                Title       = model.Title,
                Author      = model.Author,
                Content     = model.Content,
                Tags        = model.Tags,
                CreatedDate = now,
                UpdatedDate = now
            };

            await _postRepository.CreatePostAsync(post);

            return(Ok(PostDTO.GetFrom(post)));
        }
        public async Task <IActionResult> DeletePostAsync([FromRoute] int postId)
        {
            var currentFunctionCodes = GetCurrentAccountFunctionCodes();
            var post = await _postRepository.GetPostByIdAsync(postId);

            if (post == null)
            {
                throw new NotFound404Exception("post");
            }

            if (!currentFunctionCodes.Contains("Post_Full"))
            {
                if (!currentFunctionCodes.Contains("Post_Delete_All"))
                {
                    if (CurrentAccountId != post.AccountId)
                    {
                        throw new ForbiddenException();
                    }
                }

                var currentAccount = await _accountRepository.GetAccountByIdAsync(CurrentAccountId);

                var account = await _accountRepository.GetAccountByIdAsync(post.AccountId);

                if (currentAccount.GroupId > account.GroupId)
                {
                    throw new ForbiddenException(); // the lower the group id, the higher the authority; can only delete the group with authority lower than the current group
                }
            }

            post.IsDeleted   = true;
            post.UpdatedDate = DateTime.Now;

            await _postRepository.UpdatePostAsync(post);

            return(Ok(PostDTO.GetFrom(post)));
        }