Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submission for April Pull Request #16

Open
wants to merge 75 commits into
base: AprilPR
Choose a base branch
from
Open

Conversation

nadimakk
Copy link
Owner

No description provided.

nadimakk and others added 30 commits February 18, 2023 17:00
Run tests without building again.
Run tests without building again.
Included connection strings in environment of integration tests to remove them from app_settings.
@nadimakk nadimakk requested a review from nehmebilal April 26, 2023 17:27
}
catch (MessageExistsException e)
{
_logger.LogError(e, "Error adding message: {ErrorMessage}", e.Message);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to log an error here (an error means something went wrong in your service that developers should know about), the conflict will show up in the logs

Comment on lines 8 to 9
Task<SendMessageResponse> AddMessage(string conversationId, bool isFirstMessage, SendMessageRequest request);
Task<SendMessageResponse> AddFirstMessage(string conversationId, SendMessageRequest request);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need both here? An API should be minimal


public interface IUserConversationService
{
Task<StartConversationResult> CreateConversation(StartConversationRequest request);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create or Start? :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to be consistent with naming

Text = request.Text
};

await _messageStore.AddMessage(conversationId, message);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the message already exists because of a partial failure in the previous attempt? The modified time would not be updated


private void AuthorizeSender(string conversationId, string senderUsername)
{
string[] usernames = ConversationIdUtilities.SplitConversationId(conversationId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that the split is happening here and the concatenation elsewhere is problematic. This class should not depend on implementation details happening elsewhere that can change, otherwise the coupling is too tight. Also from readability perspective, I can't tell at the moment where the concatenation is happening.


string username1 = request.Participants.ElementAt(0);
string username2 = request.Participants.ElementAt(1);
string conversationId = ConversationIdUtilities.GenerateConversationId(username1, username2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we go, so the concatenation is happening here and the split elsewhere.. that's a problem. It should only be known to one class

Task AddMessage(string conversationId, Message message);
Task<Message?> GetMessage(string conversationId, string messageId);
Task<GetMessagesResult> GetMessages(string conversationId, GetMessagesParameters parameters);
Task<bool> ConversationPartitionExists(string conversationId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the concept of partition is a cosmos implementation detail, it should not be part of the interface


public interface IUserConversationStore
{
Task UpsertUserConversation(UserConversation userConversation);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ideally shouldn't be an upsert, it should be an Add that throws if the conversation already exists


public class ConversationIdUtilities
{
private static readonly char Seperator = '_';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's good that you moved this to a utility but this should be only used by one class in the application, otherwise classes would depend on each other implementations not just their interfaces.

Copy link
Collaborator

@nehmebilal nehmebilal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great overall, good work! You have room for improvement with responsibilities especially around the concatenation of username which is a concept that several classes are depending on. Ideally, this should be buried in the conversations store or the conversation service and no one else should need to know about (not even the tests).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants