Skip to content

Commit

Permalink
feat: Moving the conversation under tag (#111)
Browse files Browse the repository at this point in the history
* feat: Moving the conversation under tag
---------

Co-authored-by: Manikandan Sellasamy <[email protected]>
  • Loading branch information
manikandan5027 and Manikandan Sellasamy authored Oct 9, 2023
1 parent b35de94 commit 936663b
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 165 deletions.
11 changes: 5 additions & 6 deletions datasheetapi/Adapters/ConversationAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace datasheetapi.Adapters;
public static class ConversationAdapter
{
public static Conversation ToModel(this ConversationDto conversationDto,
Guid reviewId,
Guid projectId, string tagNo,
Guid azureUniqueId)
{
MessageDto messageDto = new()
Expand All @@ -14,7 +14,8 @@ public static Conversation ToModel(this ConversationDto conversationDto,
Property = conversationDto.Property,
ConversationLevel = MapConversationLevelDTOToModel(conversationDto.ConversationLevel),
ConversationStatus = MapConversationStatusDTOToModel(conversationDto.ConversationStatus),
TagDataReviewId = reviewId,
ProjectId = projectId,
TagNo = tagNo,
Messages = new List<Message> { messageDto.ToMessageModel(azureUniqueId) },
Participants = new List<Participant> { ToParticipantModel(azureUniqueId) }
};
Expand Down Expand Up @@ -78,8 +79,7 @@ private static ConversationLevel MapConversationLevelDTOToModel(ConversationLeve
return dto switch
{
ConversationLevelDto.Tag => ConversationLevel.Tag,
ConversationLevelDto.PurchaserRequirement => ConversationLevel.PurchaserRequirement,
ConversationLevelDto.SupplierOfferedValue => ConversationLevel.SupplierOfferedValue,
ConversationLevelDto.Property => ConversationLevel.Property,
_ => throw new ArgumentOutOfRangeException(nameof(dto), $"Unknown status: {dto}"),
};
}
Expand All @@ -101,8 +101,7 @@ private static ConversationLevelDto MapConversationLevelModelToDto(ConversationL
return model switch
{
ConversationLevel.Tag => ConversationLevelDto.Tag,
ConversationLevel.PurchaserRequirement => ConversationLevelDto.PurchaserRequirement,
ConversationLevel.SupplierOfferedValue => ConversationLevelDto.SupplierOfferedValue,
ConversationLevel.Property => ConversationLevelDto.Property,
_ => throw new ArgumentOutOfRangeException(nameof(model), $"Unknown status: {model}"),
};
}
Expand Down
92 changes: 13 additions & 79 deletions datasheetapi/Controllers/ConversationsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace datasheetapi.Controllers;

[ApiController]
[Route("/tag/reviews/{reviewId}/conversations")]
[Route("/projects/{projectId}/tags/{tagNo}/conversations")]
[Authorize]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
[RequiresApplicationRoles(
Expand All @@ -31,9 +31,11 @@ public ConversationsController(ILoggerFactory loggerFactory,

[HttpPost(Name = "CreateConversation")]
public async Task<ActionResult<GetConversationDto>> CreateConversation(
[FromRoute][NotEmptyGuid] Guid reviewId, [FromBody][Required] ConversationDto conversation)
[FromRoute][NotEmptyGuid] Guid projectId,
[FromRoute][Required] string tagNo,
[FromBody][Required] ConversationDto conversation)
{
_logger.LogDebug("Creating new conversation in the review {reviewId}.", reviewId);
_logger.LogDebug("Creating new conversation in the tagNo {tagNo}.", tagNo);
if (conversation.Property != null)
{
if (!ValidateProperty<InstrumentPurchaserRequirement>(conversation.Property) &&
Expand All @@ -45,8 +47,9 @@ public async Task<ActionResult<GetConversationDto>> CreateConversation(
}

var savedConversation = await _conversationService.CreateConversation(
conversation.ToModel(reviewId, Utils.GetAzureUniqueId(HttpContext.User)));
_logger.LogInformation("Created new conversation in the review {reviewId}.", reviewId);
conversation.ToModel(projectId, tagNo, Utils.GetAzureUniqueId(HttpContext.User)));
_logger.LogInformation(
"Created new conversation in tag {tagNo} & project {projectId}.", tagNo, projectId);

var userIdNameMap = await _conversationService.GetUserIdUserName(
savedConversation.Participants.Select(p => p.UserId).ToList());
Expand All @@ -55,9 +58,9 @@ public async Task<ActionResult<GetConversationDto>> CreateConversation(

[HttpGet("{conversationId}", Name = "GetConversation")]
public async Task<ActionResult<GetConversationDto>> GetConversation(
[NotEmptyGuid] Guid reviewId, [NotEmptyGuid] Guid conversationId)
[NotEmptyGuid] Guid projectId, [Required] string tagNo, [NotEmptyGuid] Guid conversationId)
{
_logger.LogDebug("Fetching conversation on the reviewId {reviewId}", reviewId);
_logger.LogDebug("Fetching conversation for tagNo {tagNo} & project {projectId}", tagNo, projectId);
var conversation = await _conversationService.GetConversation(conversationId);

var userIdNameMap = await _conversationService.GetUserIdUserName(
Expand All @@ -75,11 +78,11 @@ public async Task<ActionResult<GetConversationDto>> GetConversation(
/// The latest message will be non soft deleted message if at least one exists, else it will send last soft deleted message.</param>
/// <returns></returns>
[HttpGet(Name = "GetConversations")]
public async Task<ActionResult<List<GetConversationDto>>> GetConversations([NotEmptyGuid] Guid reviewId,
[FromQuery] bool includeLatestMessage = false)
public async Task<ActionResult<List<GetConversationDto>>> GetConversations([NotEmptyGuid] Guid projectId,
[Required] string tagNo, [FromQuery] bool includeLatestMessage = false)
{

var conversations = await _conversationService.GetConversations(reviewId, includeLatestMessage);
var conversations = await _conversationService.GetConversations(projectId, tagNo, includeLatestMessage);

var userIds = conversations.SelectMany(conversation =>
conversation.Participants.Select(p => p.UserId)).ToList();
Expand All @@ -88,75 +91,6 @@ public async Task<ActionResult<List<GetConversationDto>>> GetConversations([NotE
return conversations.Select(conversation => conversation.ToDto(userIdNameMap)).ToList();
}

[HttpPost("{conversationId}/messages", Name = "AddMessage")]
public async Task<ActionResult<GetMessageDto>> AddMessage(
[FromRoute][NotEmptyGuid] Guid reviewId, [FromRoute][NotEmptyGuid] Guid conversationId,
[Required] MessageDto messageDto)
{
_logger.LogDebug("Adding new message in the {conversationId} of review {reviewId}.",
conversationId, reviewId);
var message = messageDto.ToMessageModel(Utils.GetAzureUniqueId(HttpContext.User));

var savedMessage = await _conversationService.AddMessage(conversationId, message);
_logger.LogInformation("Added new message in the conversation {conversationId}.", conversationId);

return savedMessage.ToMessageDto(await _conversationService.GetUserName(savedMessage.UserId));
}

[HttpGet("{conversationId}/messages/{messageId}", Name = "GetMessage")]
public async Task<ActionResult<GetMessageDto>> GetMessage(
[NotEmptyGuid] Guid reviewId, [NotEmptyGuid] Guid conversationId, [NotEmptyGuid] Guid messageId)
{
_logger.LogDebug("Fetching message on the conversation {conversationId} of review {reviewId}", conversationId, reviewId);
var message = await _conversationService.GetMessage(messageId);
var username = await _conversationService.GetUserName(message.UserId);

return message.ToMessageDto(username);
}

[HttpGet("{conversationId}/messages", Name = "GetMessages")]
public async Task<ActionResult<List<GetMessageDto>>> GetMessages(
[NotEmptyGuid] Guid reviewId, [NotEmptyGuid] Guid conversationId)
{
_logger.LogDebug("Fetching messages on the conversation {conversationId} of review {reviewId}",
conversationId, reviewId);
var messges = await _conversationService.GetMessages(conversationId);

var userIdNameMap = await _conversationService.GetUserIdUserName(
messges.Select(c => c.UserId).ToList());

return messges.ToMessageDtos(userIdNameMap);
}

[HttpPut("{conversationId}/messages/{messageId}", Name = "UpdateMessage")]
public async Task<ActionResult<GetMessageDto>> UpdateMessage(
[FromRoute][NotEmptyGuid] Guid reviewId, [FromRoute][NotEmptyGuid] Guid conversationId,
[FromRoute][NotEmptyGuid] Guid messageId, [Required] MessageDto newMessageDto)
{
_logger.LogDebug("Updating the message {messageId}.", messageId);
var newMessage = newMessageDto.ToMessageModel(Utils.GetAzureUniqueId(HttpContext.User));

var message = await _conversationService.UpdateMessage(messageId, newMessage);
_logger.LogInformation("Updated the message {messageId} on the conversation {conversationId} of review {reviewId}.",
messageId, conversationId, reviewId);

var userName = await _conversationService.GetUserName(message.UserId);
return message.ToMessageDto(userName);

}

[HttpDelete("{conversationId}/messages/{messageId}", Name = "DeleteMessage")]
public async Task<ActionResult> DeleteMessage([FromRoute][NotEmptyGuid] Guid reviewId,
[FromRoute][NotEmptyGuid] Guid conversationId, [FromRoute][NotEmptyGuid] Guid messageId)
{
_logger.LogDebug("Deleting the message {messageId} on conversation {conversationId}.", messageId, conversationId);
await _conversationService.DeleteMessage(messageId, Utils.GetAzureUniqueId(HttpContext.User));
_logger.LogInformation("Deleted the message {messageId} on conversation {conversationId} of review {reviewId}.",
messageId, conversationId, reviewId);

return NoContent();
}

private static bool ValidateProperty<T>(string propertyName)
where T : class, new()
{
Expand Down
95 changes: 95 additions & 0 deletions datasheetapi/Controllers/MessagesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System.ComponentModel.DataAnnotations;

using datasheetapi.Adapters;

using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web.Resource;

namespace datasheetapi.Controllers;

[ApiController]
[Route("/conversations")]
[Authorize]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
[RequiresApplicationRoles(
ApplicationRole.Admin,
ApplicationRole.ReadOnlyUser,
ApplicationRole.User
)]
public class MessagesController : ControllerBase
{
private readonly IConversationService _conversationService;
private readonly ILogger<MessagesController> _logger;

public MessagesController(ILoggerFactory loggerFactory,
IConversationService conversationService)
{
_logger = loggerFactory.CreateLogger<MessagesController>();
_conversationService = conversationService;
}

[HttpPost("{conversationId}/messages", Name = "AddMessage")]
public async Task<ActionResult<GetMessageDto>> AddMessage(
[FromRoute][NotEmptyGuid] Guid conversationId, [Required] MessageDto messageDto)
{
_logger.LogDebug("Adding new message in the {conversationId}", conversationId);
var message = messageDto.ToMessageModel(Utils.GetAzureUniqueId(HttpContext.User));

var savedMessage = await _conversationService.AddMessage(conversationId, message);
_logger.LogInformation("Added new message in the conversation {conversationId}.", conversationId);

return savedMessage.ToMessageDto(await _conversationService.GetUserName(savedMessage.UserId));
}

[HttpGet("{conversationId}/messages/{messageId}", Name = "GetMessage")]
public async Task<ActionResult<GetMessageDto>> GetMessage(
[NotEmptyGuid] Guid conversationId, [NotEmptyGuid] Guid messageId)
{
_logger.LogDebug("Fetching message on the conversation {conversationId}.", conversationId);
var message = await _conversationService.GetMessage(messageId);
var username = await _conversationService.GetUserName(message.UserId);

return message.ToMessageDto(username);
}

[HttpGet("{conversationId}/messages", Name = "GetMessages")]
public async Task<ActionResult<List<GetMessageDto>>> GetMessages([NotEmptyGuid] Guid conversationId)
{
_logger.LogDebug("Fetching messages on the conversation {conversationId}.", conversationId);
var messges = await _conversationService.GetMessages(conversationId);

var userIdNameMap = await _conversationService.GetUserIdUserName(
messges.Select(c => c.UserId).ToList());

return messges.ToMessageDtos(userIdNameMap);
}

[HttpPut("{conversationId}/messages/{messageId}", Name = "UpdateMessage")]
public async Task<ActionResult<GetMessageDto>> UpdateMessage(
[FromRoute][NotEmptyGuid] Guid conversationId, [FromRoute][NotEmptyGuid] Guid messageId,
[Required] MessageDto newMessageDto)
{
_logger.LogDebug("Updating the message {messageId}.", messageId);
var newMessage = newMessageDto.ToMessageModel(Utils.GetAzureUniqueId(HttpContext.User));

var message = await _conversationService.UpdateMessage(messageId, newMessage);
_logger.LogInformation("Updated the message {messageId} on the conversation {conversationId}.",
messageId, conversationId);

var userName = await _conversationService.GetUserName(message.UserId);
return message.ToMessageDto(userName);

}

[HttpDelete("{conversationId}/messages/{messageId}", Name = "DeleteMessage")]
public async Task<ActionResult> DeleteMessage(
[FromRoute][NotEmptyGuid] Guid conversationId, [FromRoute][NotEmptyGuid] Guid messageId)
{
_logger.LogDebug("Deleting the message {messageId} on conversation {conversationId}.", messageId, conversationId);
await _conversationService.DeleteMessage(messageId, Utils.GetAzureUniqueId(HttpContext.User));
_logger.LogInformation("Deleted the message {messageId} on conversation {conversationId}.",
messageId, conversationId);

return NoContent();
}
}
3 changes: 1 addition & 2 deletions datasheetapi/Dtos/Conversation/ConversationLevelDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ namespace datasheetapi.Dtos;
public enum ConversationLevelDto
{
Tag,
PurchaserRequirement,
SupplierOfferedValue,
Property,
}
13 changes: 3 additions & 10 deletions datasheetapi/Models/Conversation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,19 @@ namespace datasheetapi.Models;

public class Conversation : BaseEntity
{
public Guid ProjectId { get; set; }
public string TagNo { get; set; } = string.Empty;
public string? Property { get; set; }
public ConversationLevel ConversationLevel { get; set; }
public ConversationStatus ConversationStatus { get; set; }
public List<Participant> Participants { get; set; } = new List<Participant>();
public List<Message> Messages { get; set; } = new List<Message>();
public Guid TagDataReviewId { get; set; }
public TagDataReview? TagDataReview { get; set; }

public void SetTagDataReview(TagDataReview review)
{
TagDataReviewId = review.Id;
TagDataReview = review;
}
}

public enum ConversationLevel
{
Tag,
PurchaserRequirement,
SupplierOfferedValue,
Property,
}


Expand Down
9 changes: 5 additions & 4 deletions datasheetapi/Repositories/ConversationRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,19 @@ public async Task<Conversation> CreateConversation(Conversation conversation)
.Where(p => p.Id == conversationId).FirstOrDefaultAsync();
}

public async Task<List<Conversation>> GetConversations(Guid reviewId)
public async Task<List<Conversation>> GetConversations(Guid projectId, string tagNo)
{
return await _context.Conversations
.Include(c => c.Participants)
.Where(c => c.TagDataReviewId == reviewId).ToListAsync();
.Where(c => c.ProjectId == projectId && c.TagNo == tagNo).ToListAsync();
}

public async Task<List<Conversation>> GetConversationsWithLatestMessage(Guid reviewId, bool includeSoftDeletedMessage)
public async Task<List<Conversation>> GetConversationsWithLatestMessage(Guid projectId,
string tagNo, bool includeSoftDeletedMessage)
{
var conversationWithLatestMessage = await _context.Conversations
.Include(c => c.Participants)
.Where(c => c.TagDataReviewId == reviewId)
.Where(c => c.ProjectId == projectId && c.TagNo == tagNo)
.Select(c => new
{
Conversation = c,
Expand Down
5 changes: 3 additions & 2 deletions datasheetapi/Repositories/IConversationRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ public interface IConversationRepository
{
Task<Conversation> CreateConversation(Conversation conversation);
Task<Conversation?> GetConversation(Guid conversationId);
Task<List<Conversation>> GetConversationsWithLatestMessage(Guid reviewId, bool includeSoftDeletedMessage);
Task<List<Conversation>> GetConversations(Guid reviewId);
Task<List<Conversation>> GetConversationsWithLatestMessage(Guid projectId,
string tagNo, bool includeSoftDeletedMessage);
Task<List<Conversation>> GetConversations(Guid projectId, string tagNo);

Task<Message> AddMessage(Message message);
Task<Message?> GetMessage(Guid messageId);
Expand Down
Loading

0 comments on commit 936663b

Please sign in to comment.