Skip to content
This repository has been archived by the owner on Nov 6, 2023. It is now read-only.

Commit

Permalink
CQRS pattern refactor (#3)
Browse files Browse the repository at this point in the history
* CQRS refactor
  • Loading branch information
Hy0tic committed Jul 9, 2023
1 parent 1628da5 commit 96c4be3
Show file tree
Hide file tree
Showing 32 changed files with 364 additions and 227 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Build and Test

on:
on:
pull_request:
types: [ opened, synchronize, closed ]
workflow_dispatch:
Expand Down Expand Up @@ -52,6 +52,4 @@ jobs:
# dotnet build --configuration Release

# - name: Build docker image
# run: docker build -t ${{secrets.DOCKER_USERNAME}}/toff-api .


# run: docker build -t ${{secrets.DOCKER_USERNAME}}/toff-api .
6 changes: 2 additions & 4 deletions .github/workflows/main_toffapi-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,8 @@ jobs:
slot-name: 'Production'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_1F42E00472304031AE7CD91B89400550 }}
package: .

- name: Clean up Artifacts
uses: geekyeggo/delete-artifact@v2
with:
name: .net-app


name: .net-app
9 changes: 1 addition & 8 deletions ToffApi/Command/CommandBuses/Command.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
namespace ToffApi.Command.CommandBuses;

public abstract class Command
{
protected Command(IHttpContextAccessor callerContext)
{
CallerContext = callerContext;
}

public IHttpContextAccessor CallerContext;
}
{}
5 changes: 1 addition & 4 deletions ToffApi/Command/CommandBuses/SendDmMessageCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ namespace ToffApi.Command.CommandBuses;

public class SendDmMessageCommand
{
public SendDmMessageCommand()
{

}
public SendDmMessageCommand(){}

public Guid SenderId { get; set; }
public Guid ReceiverId { get; set; }
Expand Down
7 changes: 7 additions & 0 deletions ToffApi/Command/CommandBuses/UpdatePfpCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ToffApi.Command.CommandBuses;

public class UpdatePfpCommand : Command
{
public Guid UserId { get; set; }
public IFormFile File { get; set; }
}
89 changes: 49 additions & 40 deletions ToffApi/Command/CommandHandlers/MessageCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using ToffApi.DtoModels;
using ToffApi.Command.CommandBuses;
using ToffApi.Command.CommandResults;
using ToffApi.Exceptions;
using ToffApi.Models;
using ToffApi.Query.Queries;
using ToffApi.Query.QueryHandlers;
using ToffApi.Query.QueryResults;
using ToffApi.Services.DataAccess;

Expand All @@ -9,57 +12,63 @@ namespace ToffApi.Command.CommandHandlers;
public class MessageCommandHandler : CommandHandler
{
private readonly IMessageDataAccess _messageDataAccess;
private readonly IUserDataAccess _userDataAccess;
private readonly MessageQueryHandler _messageQueryHandler;

public MessageCommandHandler(IUserDataAccess userDataAccess, IMessageDataAccess messageDataAccess)
public MessageCommandHandler(IMessageDataAccess messageDataAccess,
MessageQueryHandler messageQueryHandler)
{
_userDataAccess = userDataAccess;
_messageDataAccess = messageDataAccess;
_messageQueryHandler = messageQueryHandler;
}


public async Task<GetConversationByIdQueryResult> HandleAsync(GetConversationByIdQuery query)
public async Task<SendDmMessageCommandResult> HandleAsync(SendDmMessageCommand command)
{
var conversationList = await _messageDataAccess.GetConversationById(query.ConversationId);
var conversation = conversationList.ToList()[0];
var conversationQueryResult = new GetConversationByIdQueryResult()
// check if conversation already exist, if it does, then get conversation
var getConversationQuery = new GetConversationBetweenUsersQuery(command.SenderId, command.ReceiverId);
var msg = new Message();
try
{
ConversationId = conversation.ConversationId,
MemberIds = conversation.MemberIds,
Messages = conversation.Messages
};

return conversationQueryResult;
}
var conversation = await _messageQueryHandler.HandleAsync(getConversationQuery);
msg = new Message()
{
ConversationId = conversation.ConversationId,
SenderId = command.SenderId,
SenderName = command.SenderName,
Content = command.Content
};

public async Task<GetConversationsByUserIdQueryResult> HandleAsync(GetConversationsByUserIdQuery query)
{
var conversationQueryResult = new GetConversationsByUserIdQueryResult();

var conversations = await _messageDataAccess.GetConversationByUserId(query.UserId);
var conversationResultList = conversations.Select(c => new ConversationDto
await _messageDataAccess.AddMessage(msg);
}
catch (ConversationNotFoundException)
{
ConversationId = c.ConversationId,
MemberIds = c.MemberIds
}).ToList();
var memberList = new List<Guid>
{
command.SenderId,
command.ReceiverId
};

foreach (var c in conversationResultList)
{
var memberMap = c.MemberIds.ToDictionary(
id => id,
id => _userDataAccess.GetUserById(id)[0].UserName
);
c.MemberMap = memberMap;
c.Messages = await _messageDataAccess.GetMessagesFromConversation(query.UserId, c.ConversationId);
c.Messages = c.Messages.OrderByDescending(m => m.Timestamp).ToList();
var c = new Conversation(memberList);
await _messageDataAccess.AddConversation(c);
msg = new Message()
{
ConversationId = c.ConversationId,
SenderId = command.SenderId,
SenderName = command.SenderName,
Content = command.Content
};
await _messageDataAccess.AddMessage(msg);
}

conversationQueryResult.ConversationList = conversationResultList;
var commandResult = new SendDmMessageCommandResult()
{
Id = msg.Id,
SenderId = msg.SenderId,
SenderName = msg.SenderName,
Content = msg.Content,
ConversationId = msg.ConversationId,
Timestamp = msg.Timestamp
};

return conversationQueryResult;
}
public Task<Conversation> GetConversationBetweenUsers(Guid userId1, Guid userId2)
{
return _messageDataAccess.GetConversationBetweenUsers(userId1, userId2);
return commandResult;
}
}
26 changes: 26 additions & 0 deletions ToffApi/Command/CommandHandlers/UserCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using ToffApi.Command.CommandBuses;
using ToffApi.Command.CommandResults;
using ToffApi.Services.CloudFlareR2Service;
using ToffApi.Services.DataAccess;

namespace ToffApi.Command.CommandHandlers;

public class UserCommandHandler : CommandHandler
{
private readonly IUserDataAccess _userDataAccess;
private readonly IR2Service _r2Service;

public UserCommandHandler(IUserDataAccess userDataAccess, IR2Service r2Service)
{
_userDataAccess = userDataAccess;
_r2Service = r2Service;
}

public async Task<UpdatePfpCommandResult> HandleAsync(UpdatePfpCommand command)
{
var pfpUrl = await _r2Service.UploadObject(command.File);
var url = await _userDataAccess.UpdateUserPfp(command.UserId, pfpUrl);
var commandResult = new UpdatePfpCommandResult() { Url = url };
return commandResult;
}
}
12 changes: 6 additions & 6 deletions ToffApi/Command/CommandResults/SendDmMessageCommandResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ namespace ToffApi.Command.CommandResults;

public class SendDmMessageCommandResult
{
public Guid Id;
public Guid ConversationId;
public string SenderName;
public Guid SenderId;
public string Content;
public DateTime Timestamp;
public Guid Id { get; set; }
public Guid ConversationId { get; set; }
public string SenderName { get; set; }
public Guid SenderId { get; set; }
public string Content { get; set; }
public DateTime Timestamp { get; set; }
}
6 changes: 6 additions & 0 deletions ToffApi/Command/CommandResults/UpdatePfpCommandResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ToffApi.Command.CommandResults;

public class UpdatePfpCommandResult
{
public string Url { get; set; }
}
13 changes: 7 additions & 6 deletions ToffApi/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ public class AuthController : Controller
private readonly IAccessTokenManager _accessTokenManager;
private readonly SignInManager<User> _signInManager;

public AuthController(UserManager<User> userManager,
public AuthController(JwtSecurityTokenHandler tokenHandler,
IHttpContextAccessor httpContextAccessor,
UserManager<User> userManager,
IAccessTokenManager accessTokenManager,
SignInManager<User> signInManager)
SignInManager<User> signInManager) : base(tokenHandler, httpContextAccessor)
{
_userManager = userManager;
_accessTokenManager = accessTokenManager;
Expand All @@ -32,7 +34,7 @@ public async Task<IActionResult> CreateUser(UserDto user)
if (!ModelState.IsValid) return Ok();
var appUser = new User
{
UserName = user.Name,
UserName = user.Username,
Email = user.Email
};

Expand Down Expand Up @@ -67,9 +69,8 @@ public async Task<IActionResult> Login([FromBody] LoginDto loginInfo)
id = appUser.Id,
username = appUser.UserName,
email = appUser.Email,
pictureUrl = appUser.PictureUrl,
Token = token
});
pictureUrl = appUser.PictureUrl
});
}
}
ModelState.AddModelError(nameof(loginInfo.Email), "Login Failed: Invalid Email or Password");
Expand Down
24 changes: 23 additions & 1 deletion ToffApi/Controllers/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,30 @@ namespace ToffApi.Controllers;

public abstract class Controller : ControllerBase
{
protected Controller()
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly JwtSecurityTokenHandler _tokenHandler;
protected Controller(JwtSecurityTokenHandler tokenHandler, IHttpContextAccessor httpContextAccessor)
{
_tokenHandler = tokenHandler;
_httpContextAccessor = httpContextAccessor;
}

internal string ExtractUserId()
{
if (_httpContextAccessor.HttpContext == null)
{
throw new UnauthorizedAccessException();
}

var tokenFromRequest = _httpContextAccessor?.HttpContext?.Request.Cookies["X-Access-Token"];

if (string.IsNullOrEmpty(tokenFromRequest))
{
throw new UnauthorizedAccessException();
}

var userId = _tokenHandler.ReadJwtToken(tokenFromRequest).Claims.First(claim => claim.Type == "userId").Value;

return userId;
}
}
8 changes: 4 additions & 4 deletions ToffApi/Controllers/HealthController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;

Expand All @@ -7,10 +8,9 @@ namespace ToffApi.Controllers;
[ApiController]
public class HealthController : Controller
{
public HealthController()
{

}
public HealthController(JwtSecurityTokenHandler tokenHandler,
IHttpContextAccessor httpContextAccessor)
: base(tokenHandler, httpContextAccessor) {}

[HttpGet("/getVersion")]
public IActionResult Version()
Expand Down
Loading

0 comments on commit 96c4be3

Please sign in to comment.