Skip to content

Commit

Permalink
Merge pull request #4 from pedronvasconcelos/development
Browse files Browse the repository at this point in the history
add: mapping + like a spixer + delete a spixer
  • Loading branch information
pedronvasconcelos authored Feb 25, 2024
2 parents d299749 + 84d82c8 commit 779791a
Show file tree
Hide file tree
Showing 34 changed files with 671 additions and 81 deletions.
5 changes: 5 additions & 0 deletions Spix.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spix.Infra", "src\Spix.Infr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spix.Api", "src\Spix.Api\Spix.Api.csproj", "{4A950028-5995-4DF7-8949-9CC6DC7278D7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sql", "sql", "{5A6EDF2F-C166-4D24-9103-566E9EC58866}"
ProjectSection(SolutionItems) = preProject
sql\create_db.sql = sql\create_db.sql
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
54 changes: 54 additions & 0 deletions sql/create_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
CREATE TABLE users (
user_id UUID PRIMARY KEY,
username VARCHAR(50) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
birth_date DATE,
country VARCHAR(50),
city VARCHAR(50),
user_language INT,
email VARCHAR(255) NOT NULL,
biography TEXT,
email_is_verified BOOLEAN,
is_active BOOLEAN,
user_location TEXT,
website VARCHAR(255),
created_at timestamp with time zone,
updated_at timestamp with time zone
);

CREATE TABLE spixers (
spixer_id UUID PRIMARY KEY,
content VARCHAR(280),
likes_count INT DEFAULT 0,
created_at timestamp with time zone,
user_id UUID,
active BOOLEAN,
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
);

CREATE TABLE spixer_likes (
like_id UUID PRIMARY KEY,
spixer_id UUID,
user_id UUID,
created_at timestamp WITH TIME ZONE,
FOREIGN KEY (spixer_id) REFERENCES spixers(spixer_id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
);

CREATE TABLE user_following (
user_id UUID NOT NULL,
following_id UUID NOT NULL,

CONSTRAINT pk_user_following PRIMARY KEY (user_id, following_id),

CONSTRAINT fk_user_following_user
FOREIGN KEY (user_id)
REFERENCES users (user_id)
ON DELETE RESTRICT,

CONSTRAINT fk_user_following_following
FOREIGN KEY (following_id)
REFERENCES users (user_id)
ON DELETE RESTRICT
);
53 changes: 51 additions & 2 deletions src/Spix.Api/Controllers/SpixerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Spix.Application.Spixers.Create;
using Spix.Application.Spixers.Delete;
using Spix.Application.Spixers.Like;
using Spix.Application.Spixers.Unlike;

namespace Spix.Api.Controllers
{
Expand All @@ -16,11 +19,57 @@ public SpixerController(IMediator mediator)
_mediator = mediator;
}

[HttpPost]
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> CreateSpixer([FromBody] CreateSpixerCommand command)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var response = await _mediator.Send(command);
return Ok(response);
}
}

[HttpPost]
[Route("[action]")]
public async Task<IActionResult> LikeSpixer([FromBody] LikeASpixerCommand command)
{

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var response = await _mediator.Send(command);
return Ok(response);
}

[HttpPost]
[Route("[action]")]
public async Task<IActionResult> UnlikeSpixer([FromBody] UnlikeASpixerCommand command)
{

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var response = await _mediator.Send(command);
return Ok(response);
}

[HttpDelete]
[Route("[action]")]
public async Task<IActionResult> DeleteSpixer([FromBody] Guid guid)
{

if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var command = new DeleteSpixerCommand(Guid.NewGuid(), guid);
var response = await _mediator.Send(command);
return Ok(response);
}
}
}
6 changes: 0 additions & 6 deletions src/Spix.Api/Spix.Api.http

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ public CreateSpixerCommandHandler(ISpixerRepository spixerRepository, IUserRepos
public async Task<ResultBase<CreateSpixerResponse>> Handle(CreateSpixerCommand request, CancellationToken cancellationToken)
{

/* var user = await _userRepository.GetAsync(request.UserId);
var user = await _userRepository.GetByIdAsync(request.UserId);
if (user == null)
{
return ResultBaseFactory.Failure<CreateSpixerResponse>("User not found");
}
*/
var spixer = new Spixer(request.Content, request.UserId);

var spixer = new Spixer(request.Content, user.Id);
var addedSpixer = await _spixerRepository.AddAsync(spixer);

if (await _spixerRepository.UnitOfWork.CommitAsync(cancellationToken))
if (!await _spixerRepository.UnitOfWork.CommitAsync(cancellationToken))
{
return ResultBaseFactory.Failure<CreateSpixerResponse>("Error adding spixer");
}
Expand Down
15 changes: 15 additions & 0 deletions src/Spix.Application/Spixers/Delete/DeleteSpixerCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Spix.Application.Core;

namespace Spix.Application.Spixers.Delete;

public class DeleteSpixerCommand : ICommandBase<DeleteSpixerResponse>
{
public Guid UserId { get; set; }
public Guid SpixerId { get; set; }

public DeleteSpixerCommand(Guid userId, Guid spixerId)
{
UserId = userId;
SpixerId = spixerId;
}
}
37 changes: 37 additions & 0 deletions src/Spix.Application/Spixers/Delete/DeleteSpixerCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Spix.Application.Core;
using Spix.Domain.Spixers;

namespace Spix.Application.Spixers.Delete;

public class DeleteSpixerCommandHandler : ICommandHandlerBase<DeleteSpixerCommand, DeleteSpixerResponse>
{
private readonly ISpixerRepository _spixerRepository;

public DeleteSpixerCommandHandler(ISpixerRepository spixerRepository)
{
_spixerRepository = spixerRepository;
}

public async Task<ResultBase<DeleteSpixerResponse>> Handle(DeleteSpixerCommand request, CancellationToken cancellationToken)
{

var spixer = await _spixerRepository.GetByIdAsync(request.SpixerId);
if (spixer == null)
{
return ResultBaseFactory.Failure<DeleteSpixerResponse>("Spixer not found");
}

if (spixer.UserId != request.UserId)
{
return ResultBaseFactory.Failure<DeleteSpixerResponse>("User not authorized to delete this spixer");
}

spixer.Delete();
await _spixerRepository.UpdateAsync(spixer);
if (!await _spixerRepository.UnitOfWork.CommitAsync(cancellationToken))
{
return ResultBaseFactory.Failure<DeleteSpixerResponse>("Error deleting spixer");
}
return ResultBaseFactory.Successful(new DeleteSpixerResponse { DeletedAt = DateTime.UtcNow }, "Success");
}
}
6 changes: 6 additions & 0 deletions src/Spix.Application/Spixers/Delete/DeleteSpixerResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Spix.Application.Spixers.Delete;

public class DeleteSpixerResponse
{
public DateTime DeletedAt { get; set; }
}
14 changes: 14 additions & 0 deletions src/Spix.Application/Spixers/Like/LikeASpixerCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Spix.Application.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Spix.Application.Spixers.Like;

public class LikeASpixerCommand : ICommandBase<LikeASpixerResponse>
{
public Guid UserId { get; set; }
public Guid SpixerId { get; set; }
}
57 changes: 57 additions & 0 deletions src/Spix.Application/Spixers/Like/LikeASpixerCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Spix.Application.Core;
using Spix.Domain.Likes;
using Spix.Domain.Spixers;
using Spix.Domain.Users;

namespace Spix.Application.Spixers.Like;

public class LikeASpixerCommandHandler : ICommandHandlerBase<LikeASpixerCommand, LikeASpixerResponse>
{
private readonly ISpixerRepository _spixerRepository;
private readonly IUserRepository _userRepository;

public LikeASpixerCommandHandler(ISpixerRepository spixerRepository, IUserRepository userRepository)
{
_spixerRepository = spixerRepository;
_userRepository = userRepository;
}
public async Task<ResultBase<LikeASpixerResponse>> Handle(LikeASpixerCommand request, CancellationToken cancellationToken)
{

var user = await _userRepository.GetByIdAsync(request.UserId);
if (user == null)
{
return ResultBaseFactory.Failure<LikeASpixerResponse>("User not found");
}
var spixer = await _spixerRepository.GetByIdAsync(request.SpixerId);
if (spixer == null)
{
return ResultBaseFactory.Failure<LikeASpixerResponse>("Spixer not found");
}
if (await _spixerRepository.IsSpixerLikedByUserAsync(request.SpixerId, request.UserId))
{
return ResultBaseFactory.Failure<LikeASpixerResponse>("Spixer already liked");
}

var spixerLike = new SpixerLike(spixer.Id, user.Id);
spixer.Like(spixerLike);


await _spixerRepository.UpdateAsync(spixer);
await _spixerRepository.AddSpixerLikeAsync(spixerLike);
if (!await _spixerRepository.UnitOfWork.CommitAsync(cancellationToken))
{
return ResultBaseFactory.Failure<LikeASpixerResponse>("Error liking spixer");
}



return ResultBaseFactory.Successful(
new LikeASpixerResponse(
spixerLike.Id,
user.Id,
spixer.Id,
spixerLike.CreatedAt),
"Success");
}
}
17 changes: 17 additions & 0 deletions src/Spix.Application/Spixers/Like/LikeASpixerResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Spix.Application.Spixers.Like;

public class LikeASpixerResponse
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public Guid SpixerId { get; set; }
public DateTime CreatedAt { get; set; }

public LikeASpixerResponse(Guid id, Guid userId, Guid spixerId, DateTime createdAt)
{
Id = id;
UserId = userId;
SpixerId = spixerId;
CreatedAt = createdAt;
}
}
9 changes: 9 additions & 0 deletions src/Spix.Application/Spixers/Unlike/UnlikeASpixerCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Spix.Application.Core;

namespace Spix.Application.Spixers.Unlike;

public class UnlikeASpixerCommand : ICommandBase<UnlikeASpixerResponse>
{
public Guid UserId { get; set; }
public Guid SpixerId { get; set; }
}
53 changes: 53 additions & 0 deletions src/Spix.Application/Spixers/Unlike/UnlikeASpixerCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

using Spix.Application.Core;
using Spix.Domain.Spixers;
using Spix.Domain.Users;

namespace Spix.Application.Spixers.Unlike;

public class UnlikeASpixerCommandHandler : ICommandHandlerBase<UnlikeASpixerCommand, UnlikeASpixerResponse>
{
private readonly ISpixerRepository _spixerRepository;
private readonly IUserRepository _userRepository;

public UnlikeASpixerCommandHandler(ISpixerRepository spixerRepository, IUserRepository userRepository)
{
_spixerRepository = spixerRepository;
_userRepository = userRepository;
}
public async Task<ResultBase<UnlikeASpixerResponse>> Handle(UnlikeASpixerCommand request, CancellationToken cancellationToken)
{

var user = await _userRepository.GetByIdAsync(request.UserId);
if (user == null)
{
return ResultBaseFactory.Failure<UnlikeASpixerResponse>("User not found");
}
var spixer = await _spixerRepository.GetByIdAsync(request.SpixerId);
if (spixer == null)
{
return ResultBaseFactory.Failure<UnlikeASpixerResponse>("Spixer not found");
}

var like = await _spixerRepository.GetSpixerLikeAsync(request.SpixerId, request.UserId);
if(like == null)
{
return ResultBaseFactory.Failure<UnlikeASpixerResponse>("Spixer not liked");
}

spixer.Unlike(like);
await _spixerRepository.DeleteSpixerLikeAsync(like);


await _spixerRepository.UpdateAsync(spixer);
if (!await _spixerRepository.UnitOfWork.CommitAsync(cancellationToken))
{
return ResultBaseFactory.Failure<UnlikeASpixerResponse>("Error liking spixer");
}



return ResultBaseFactory.Successful(
new UnlikeASpixerResponse(spixer.Id, request.UserId));
}
}
13 changes: 13 additions & 0 deletions src/Spix.Application/Spixers/Unlike/UnlikeASpixerResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Spix.Application.Spixers.Unlike;

public class UnlikeASpixerResponse
{
public Guid SpixerId { get; set; }
public Guid UserId { get; set; }

public UnlikeASpixerResponse(Guid spixerId, Guid userId)
{
SpixerId = spixerId;
UserId = userId;
}
}
Loading

0 comments on commit 779791a

Please sign in to comment.