Skip to content

Commit

Permalink
feat: Get conversations for container (#121)
Browse files Browse the repository at this point in the history
* feat: Add endpoint to get conversations for a single container
  • Loading branch information
taustad authored Nov 7, 2023
1 parent c7d5ee1 commit 8a724f7
Show file tree
Hide file tree
Showing 17 changed files with 83 additions and 12 deletions.
3 changes: 3 additions & 0 deletions datasheetapi/Adapters/ConversationAdapter.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using datasheetapi.Dtos.Conversation;

namespace datasheetapi.Adapters;
public static class ConversationAdapter
{
Expand Down Expand Up @@ -29,6 +31,7 @@ public static GetConversationDto ToDto(this Conversation conversation,
Id = conversation.Id,
CreatedDate = conversation.CreatedDate,
ModifiedDate = conversation.ModifiedDate,
TagNo = conversation.TagNo,
Property = conversation.Property,
ConversationLevel = MapConversationLevelModelToDto(conversation.ConversationLevel),
ConversationStatus = MapConversationStatusModelToDto(conversation.ConversationStatus),
Expand Down
30 changes: 29 additions & 1 deletion datasheetapi/Controllers/ContainersController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using datasheetapi.Adapters;
using datasheetapi.Dtos.Conversation;
using datasheetapi.Exceptions;

using Fusion;

using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web.Resource;
Expand All @@ -17,12 +21,21 @@ namespace datasheetapi.Controllers;
public class ContainersController : ControllerBase
{
private readonly IContainerService _containerService;
private readonly IConversationService _conversationService;
private readonly ILogger<ContractsController> _logger;
private readonly IUserService _userService;

public ContainersController(ILoggerFactory loggerFactory, IContainerService containerService)
public ContainersController(
ILoggerFactory loggerFactory,
IContainerService containerService,
IConversationService conversationService,
IUserService userService
)
{
_logger = loggerFactory.CreateLogger<ContractsController>();
_containerService = containerService;
_conversationService = conversationService;
_userService = userService;
}

[HttpGet("{containerId}")]
Expand All @@ -39,4 +52,19 @@ public async Task<ActionResult<List<ContainerDto>>> GetContainers()
return contracts.ToDto();
}

[HttpGet("{containerId}/conversations")]
public async Task<ActionResult<List<GetConversationDto>>> GetConversations([NotEmptyGuid] Guid containerId)
{
var container = await _containerService.GetContainer(containerId) ??
throw new NotFoundException($"Container with id {containerId} not found");

var tagNos = container.Tags.Select(t => t.TagNo).ToList();
var conversations = await _conversationService.GetConversationsForTagNos(tagNos);

var userIds = conversations.SelectMany(conversation =>
conversation.Participants.Select(p => p.UserId)).ToList();
var userIdNameMap = await _userService.GetDisplayNames(userIds);

return conversations.Select(conversation => conversation.ToDto(userIdNameMap)).ToList();
}
}
3 changes: 2 additions & 1 deletion datasheetapi/Controllers/ConversationsController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;

using datasheetapi.Adapters;
using datasheetapi.Dtos.Conversation;
using datasheetapi.Exceptions;

using Microsoft.AspNetCore.Authorization;
Expand Down Expand Up @@ -79,7 +80,7 @@ public async Task<ActionResult<GetConversationDto>> GetConversation(
/// Get the list of conversation available under the reviewId
/// </summary>
/// <param name="reviewId">Unique Id for the review</param>
/// <param name="includeLatestMessage">Include Latest Message in the conversation.
/// <param name="includeLatestMessage">Include Latest Message in the conversation.
/// 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")]
Expand Down
1 change: 1 addition & 0 deletions datasheetapi/Controllers/MessagesController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;

using datasheetapi.Adapters;
using datasheetapi.Dtos.Conversation;

using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web.Resource;
Expand Down
2 changes: 1 addition & 1 deletion datasheetapi/Dtos/Conversation/ConversationDto.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;

namespace datasheetapi.Dtos;
namespace datasheetapi.Dtos.Conversation;
public record ConversationDto
{
[MaxLength(500)]
Expand Down
2 changes: 1 addition & 1 deletion datasheetapi/Dtos/Conversation/ConversationLevelDto.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace datasheetapi.Dtos;
namespace datasheetapi.Dtos.Conversation;

public enum ConversationLevelDto
{
Expand Down
2 changes: 1 addition & 1 deletion datasheetapi/Dtos/Conversation/ConversationStatusDto.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace datasheetapi.Dtos;
namespace datasheetapi.Dtos.Conversation;

public enum ConversationStatusDto
{
Expand Down
8 changes: 6 additions & 2 deletions datasheetapi/Dtos/Conversation/GetConversationDto.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
namespace datasheetapi.Dtos;
public record GetConversationDto : BaseEntityDto
namespace datasheetapi.Dtos.Conversation;
public class GetConversationDto
{
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string TagNo { get; set; } = string.Empty;
public string? Property { get; set; }
public ConversationStatusDto ConversationStatus { get; set; }
public ConversationLevelDto ConversationLevel { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion datasheetapi/Dtos/Conversation/GetMessageDto.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;

namespace datasheetapi.Dtos;
namespace datasheetapi.Dtos.Conversation;
public record GetMessageDto : BaseEntityDto
{
public Guid UserId { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion datasheetapi/Dtos/Conversation/MessageDto.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;

namespace datasheetapi.Dtos;
namespace datasheetapi.Dtos.Conversation;
public record MessageDto
{
[MaxLength(500)]
Expand Down
2 changes: 1 addition & 1 deletion datasheetapi/Dtos/Conversation/UserDto.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace datasheetapi.Dtos;
namespace datasheetapi.Dtos.Conversation;
public record UserDto
{
public Guid UserId { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion datasheetapi/Repositories/ContainerRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public ContainerRepository(ILoggerFactory loggerFactory, DatabaseContext context

public async Task<Container?> GetContainer(Guid id)
{
var revisionContainer = await _context.Containers.FindAsync(id);
var revisionContainer = await _context.Containers.Include(c => c.Tags).FirstOrDefaultAsync();
return revisionContainer;
}

Expand Down
26 changes: 26 additions & 0 deletions datasheetapi/Repositories/ConversationRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,32 @@ public async Task<List<Conversation>> GetConversations(Guid projectId, string ta
.Where(c => c.ProjectId == projectId && c.TagNo == tagNo).ToListAsync();
}

public async Task<List<Conversation>> GetConversationsForTagNos(ICollection<string> tagNos)
{
var conversationWithLatestMessage = await _context.Conversations
.Include(c => c.Participants)
.Where(c => tagNos.Contains(c.TagNo))
.Select(c => new
{
Conversation = c,
LatestMessage = c.Messages
.OrderByDescending(m => m.CreatedDate)
.FirstOrDefault(m => m.SoftDeleted == false)
?? c.Messages
.OrderByDescending(m => m.CreatedDate)
.First()
})
.ToListAsync();

return conversationWithLatestMessage
.Select(c =>
{
c.Conversation.Messages = new List<Message> { c.LatestMessage };
return c.Conversation;
})
.ToList();
}

public async Task<List<Conversation>> GetConversationsWithLatestMessage(Guid projectId,
string tagNo, bool includeSoftDeletedMessage)
{
Expand Down
1 change: 1 addition & 0 deletions datasheetapi/Repositories/IConversationRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public interface IConversationRepository
{
Task<Conversation> CreateConversation(Conversation conversation);
Task<Conversation?> GetConversation(Guid conversationId);
Task<List<Conversation>> GetConversationsForTagNos(ICollection<string> tagNos);
Task<List<Conversation>> GetConversationsWithLatestMessage(Guid projectId,
string tagNo, bool includeSoftDeletedMessage);
Task<List<Conversation>> GetConversations(Guid projectId, string tagNo);
Expand Down
7 changes: 6 additions & 1 deletion datasheetapi/Services/ConversationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public ConversationService(ILoggerFactory loggerFactory,

public async Task<Conversation> CreateConversation(Conversation conversation)
{
// TODO: Not sure, how to verify the project from the tag.
// TODO: Not sure, how to verify the project from the tag.
// This needs to be relook when we have integration to FAM
_ = await _famService.GetTagData(conversation.TagNo)
?? throw new NotFoundException("Invalid tag data");
Expand All @@ -43,6 +43,11 @@ public async Task<List<Conversation>> GetConversations(Guid projectId, string ta
return await _conversationRepository.GetConversations(projectId, tagNo);
}

public async Task<List<Conversation>> GetConversationsForTagNos(ICollection<string> tagNos)
{
return await _conversationRepository.GetConversationsForTagNos(tagNos);
}

public async Task<Message> AddMessage(Guid conversationId, Message message)
{
var conversation = await _conversationRepository.GetConversation(conversationId)
Expand Down
1 change: 1 addition & 0 deletions datasheetapi/Services/IConversationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public interface IConversationService
Task<Conversation> CreateConversation(Conversation conversation);
Task<Conversation> GetConversation(Guid conversationId);
Task<List<Conversation>> GetConversations(Guid projectId, string tagNo, bool includeLatestMessage);
Task<List<Conversation>> GetConversationsForTagNos(ICollection<string> tagNos);

Task<Message> AddMessage(Guid conversationId, Message message);
Task<Message> GetMessage(Guid messageId);
Expand Down
1 change: 1 addition & 0 deletions tests/Adapters/ConversationAdapterTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using datasheetapi.Adapters;
using datasheetapi.Dtos;
using datasheetapi.Dtos.Conversation;
using datasheetapi.Models;

namespace tests.Adapters;
Expand Down

0 comments on commit 8a724f7

Please sign in to comment.