Skip to content
Snippets Groups Projects
PostEndpoints.cs 2.58 KiB
Newer Older
using ErrorOr;
using MediatR;
using Microsoft.EntityFrameworkCore;
using SocialNetwork.Social.Application.Common.Interfaces;
using SocialNetwork.Social.Application.Posts.Commands;
using SocialNetwork.Social.Domain.Entities.Feed;

namespace WebApi.Endpoints;

public class PostEndpoints
{
    public void Map(IEndpointRouteBuilder builder)
    {
        builder.MapGet("", GetAllPosts);

        builder.MapGet("/{postId:guid}", GetPostById);

        builder.MapPost("", CreatePost);

        builder.MapPost("/{postId:guid}/comments", CommentPost);

        builder.MapPost("/{postId:guid}/like", LikePost);
    }

    private async Task<IResult> GetAllPosts(ISender sender) =>
        Results.Ok(await sender.Send(new GetPostsCommand()));
    private async Task<IResult> GetPostById(Guid postId, ISender sender)
        var post = await sender.Send(new GetPostByIdCommand(postId));

        return post.MatchFirst(
            Results.Ok,
            error => error.Type switch
            {
                ErrorType.NotFound => Results.NotFound(error.Code),
                _ => Results.BadRequest(error.Code)
            }
        );
    }

    private async Task<IResult> CommentPost(Guid postId, Comment comment, IApplicationDbContext dbContext)
    {
        var post = await dbContext.Posts.FindAsync(postId);
        if (post is null) return Results.NotFound("Post not found");
        if (post.Comments.Any(c => c.Id == comment.Id)) return Results.Conflict("Comment already exists");

        comment.PostId = postId;
        await dbContext.Comments.AddAsync(comment);
        post.Comments.Add(comment);
        await dbContext.SaveChangesAsync();

        dbContext.Posts.Update(post);
        await dbContext.SaveChangesAsync();

        return Results.Created($"api/posts/{postId}", comment);
    }

    private async Task<IResult> CreatePost(Post post, IApplicationDbContext dbContext)
    {
        var doesPostExist = await dbContext.Posts.AnyAsync(p => p.Id == post.Id);
        if (doesPostExist) return Results.Conflict();

        var entry = dbContext.Posts.Add(post);
        await dbContext.SaveChangesAsync();

        var persistedPost = entry.Entity;
        return Results.Created($"/api/posts/{persistedPost.Id}", persistedPost);
    }

    private async Task<IResult> LikePost(Guid postId, Guid likerId, IApplicationDbContext dbContext)
    {
        var post = await dbContext.Posts.FindAsync(postId);
        if (post is null) return Results.NotFound();

        post.LikesCount++;
        // TODO add who liked the post
        await dbContext.SaveChangesAsync();
        return Results.Ok();
    }
}