Skip to content

Conversation

@Romainhir
Copy link
Collaborator

@Romainhir Romainhir commented Dec 16, 2024

This issue was flagged here. It is part of polishing the inconsistencies of our app. Precisely, this means :

  • Wipe the user's saved events and decrement the saved counter of those events
  • Wipe the user's followed associations and decrement the follow counter of those associations
  • Wipe the user's joined association and wipe it from the association's members list

@Romainhir Romainhir changed the title refactor(UserDeletion): add repository file to delete users Fix user delete to properly delete user's relations in the app Dec 16, 2024
@Romainhir Romainhir self-assigned this Dec 16, 2024
@Romainhir Romainhir added the bug Something isn't working label Dec 16, 2024
@Romainhir Romainhir linked an issue Dec 16, 2024 that may be closed by this pull request
@Romainhir Romainhir marked this pull request as ready for review December 16, 2024 15:01
Copy link
Collaborator

@Redd87 Redd87 left a comment

Choose a reason for hiding this comment

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

An elegant solution to the problem! However you completely forgot to comment your new functions and classes, as well as the ones you modified previously. I'm also curious as to why you overwrite the Event hashCode and equals method.
As I think I might have overlooked some aspects I'd also like someone else to look at the code

}
}

override fun deleteUser(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please comment your new functions and classes

*/
suspend fun deleteUser(
userId: String,
user: User,
Copy link
Collaborator

Choose a reason for hiding this comment

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

And modify the corresponding javadoc alongside the function

Comment on lines +62 to +74
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as Event

return uid == other.uid
}

override fun hashCode(): Int {
return uid.hashCode()
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

When do you use those?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

SonarCloud consider not implementing both equals and hashcode together as a maintanability issue, so that's why I implemented it

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok that makes sense

@Romainhir Romainhir requested a review from Redd87 December 17, 2024 07:51
@Redd87
Copy link
Collaborator

Redd87 commented Dec 17, 2024

Good job making the requested changes, I'd also just like someone else to have a look at the code as mentioned previously

@Redd87 Redd87 requested review from Zafouche and removed request for Redd87 December 17, 2024 08:46
@Romainhir Romainhir requested a review from Redd87 December 17, 2024 08:58
Copy link
Collaborator

@Zafouche Zafouche left a comment

Choose a reason for hiding this comment

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

I might be wrong but this would be a case that would fall under the domain layer category.

UserDeletionRepositoryFirestore is something that uses multiple repositories, and it is in-between the data layer, e.g. the repositories, and the UI layer, e.g. the view models.
This is exactly what the domain layer is defined as.

I suggest you (and @Redd87, have a look at it also) read about this article on the domain layer.
It describes what we do here as something that would fall in the domain layer, and that would be called a UseCase instead of a Repository.

It might seem strange because in Kotlin, calling use cases requires defining an invoke() function. I am not sure if this is 100% required but this seems to be what should be done, so it looks like a general convention. However I am not yet sure about how it would be defined in our case.

Anyways have a look at the domain layer explanation and give me your opinions. I think it would indeed fall under this category, so if we respect it then the MVVM architecture is fully respected (and we draw something under the domain layer in our architecture diagram!). If you agree, then I think the repository that was defined for the follow button would also fall in the domain category, e.g. ConcurrentAssociationUserRepositoryFirestore.

Concern:

However in both these cases, I am not sure how the runBatch would fall under this category, and how it could be replaced / done differently. Because these repos not only use multiple other repos, but also interact with the database directly, so I am not so sure about it being in the domain layer if we look at it from this perspective.

Either way, I think this might be a question worth asking the coaches.

Conclusion:

I think the current solution works well, and from the research I've done, these types of operations seem vague for everyone, meaning I haven't found a specific solution. From the looks of it, it seems up for debate. So I don't think it's really necessary to get into this right now, as the milestone is approaching, but we could definitely discuss it quickly.

@Romainhir
Copy link
Collaborator Author

I read the article and see what you mean. But doesn'r this just mean concretely that I can rename the file/class to "use case" instead of "Repository" ? In term of functionnality, I do not see any change to be done (The "invoke" operator you mentionned seems to not be mandatory to a "use case")

@Zafouche
Copy link
Collaborator

Zafouche commented Dec 18, 2024

I read the article and see what you mean. But doesn'r this just mean concretely that I can rename the file/class to "use case" instead of "Repository" ? In term of functionnality, I do not see any change to be done (The "invoke" operator you mentionned seems to not be mandatory to a "use case")

Pretty much, yeah. Anyway it would make the purpose of the class much more clear, as it fits in between the repos and the view models. And in our case, the invoke() function would correspond to the deleteUser function, and it's fine to keep it as is, since the function itself doesn't return anything like the examples of invoke() usages.

Let's wait for @Redd87's opinion, but if it's fine for him as well, this should be added in the domain layer of the architecture diagram, just like the concurrent association user repo made for the follow feature.

@Romainhir
Copy link
Collaborator Author

Ok, I'll make that change. Thank you very much for your comments, it was very helpful.

@Redd87
Copy link
Collaborator

Redd87 commented Dec 18, 2024

@Zafouche I agree with your suggestions, it makes more sense this way. I also wonder if the searchRepository qualifies as such?

@Zafouche
Copy link
Collaborator

@Zafouche I agree with your suggestions, it makes more sense this way. I also wonder if the searchRepository qualifies as such?

I wouldn't say so. The guide I mentioned says that a UseCase shouldn't contain mutable data. While it's only one object in searchRepository (only the AppSearchSession is kept as a mutable object), its use is still essential to what the repository does. Also, since it directly works with the phone's local storage for building the search database, and that UseCases are more high level than that, I would prefer keeping it as a repository. What do you think? @Redd87

Copy link
Collaborator

@Zafouche Zafouche left a comment

Choose a reason for hiding this comment

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

Good job on this! 🚀

Question: Is it hard to write tests for a batch operation?
I assume it is so I understand if they aren't added right now.

Also, just make sure to rename the repo to a UseCase and you are good to go.

Last thing, looks like the merge was rebased. If you do the merged through the terminal, I suggest you check you merging config. In this case, please just check it hasn't crushed anything that was implemented in the picture maximization feature PR, and that it is up to date with it (simple merge with main).
I honestly forgot a little how a rebase works, so be careful with that.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Depending on what you choose for the interface, either rename it to UserDeletionUseCase, or UserDeletionUseCaseFirestore. Again, I'd go for UserDeletionUseCaseFirestore.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would either delete this interface, or rename it to UserDeletionUseCase. From what I see on the guide, a UseCase is directly implemented but it could be good to keep an interface for it, so I'd say to the latter.

Comment on lines +345 to +347
@Test
fun testFullSizePictureOnClick() {
setEventScreen(events[0])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Good test addition, even though I think this is a test for a feature implemented in a different PR

Comment on lines +284 to +294
private fun <T> updateOrAdd(list: MutableList<T>, item: T, operation: (T) -> T) {
if (list.contains(item)) {
val index = list.indexOf(item)
val current = list[index]
val newItem = operation(current)
list[index] = newItem
} else {
val newItem = operation(item)
list.add(newItem)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Great addition. Add some small documentation to it though, event if it's straightforward to understand what it does.

Comment on lines +457 to +465
if (showFullScreen) {
PictureOverlay(
onDismiss = {
selectedPictureUri = Uri.EMPTY
showFullScreen = false
},
pagerState,
eventPictures)
}
Copy link
Collaborator

@Zafouche Zafouche Dec 18, 2024

Choose a reason for hiding this comment

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

Is this supposed to be from the click on image feature addition? Why does it show up like an addition? Accidental rebase again? 🤣 Anyway just make sure it's on par with the main branch, so that it doesn't crush anything.

Copy link
Collaborator

@Zafouche Zafouche Dec 18, 2024

Choose a reason for hiding this comment

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

Yep seems like you indeed merge rebased main

@Romainhir
Copy link
Collaborator Author

Romainhir commented Dec 18, 2024

Last thing, looks like the merge was rebased. If you do the merged through the terminal, I suggest you check you merging config. In this case, please just check it hasn't crushed anything that was implemented in the picture maximization feature PR, and that it is up to date with it (simple merge with main). I honestly forgot a little how a rebase works, so be careful with that.

I do not know what cause this issue. I just switched to main to create another branch and working on it before switching back to it, I don't know which step could cause this. I have to check the merge configuration

Update : I think I found where this come from. It's because I did a pull from main and because no conflict were found, git just did a "fast-forward" and register all these commit in my branch. So I think it is safe to merge this to main even with these commits that are not mine. I will be more careful in the futur to avoid "fast-forward" in PR like this.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
50.96% Line Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@Zafouche
Copy link
Collaborator

Zafouche commented Dec 18, 2024

Last thing, looks like the merge was rebased. If you do the merged through the terminal, I suggest you check you merging config. In this case, please just check it hasn't crushed anything that was implemented in the picture maximization feature PR, and that it is up to date with it (simple merge with main). I honestly forgot a little how a rebase works, so be careful with that.

I do not know what cause this issue. I just switched to main to create another branch and working on it before switching back to it, I don't know which step could cause this. I have to check the merge configuration

Update : I think I found where this come from. It's because I did a pull from main and because no conflict were found, git just did a "fast-forward" and register all these commit in my branch. So I think it is safe to merge this to main even with these commits that are not mine. I will be more careful in the futur to avoid "fast-forward" in PR like this.

Ahh I see, fair enough. Have you tried doing a last updated from main to check you pulled all the commits?

Edit: I just checked what commits were done by @armouldr on that picture maximization PR, and all of them are here, so no problem! Safe to merge.

Copy link
Collaborator

@Zafouche Zafouche left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

Also thanks on taking the initiative to also re-label to UseCases the other similar repositories we had.

@Romainhir Romainhir merged commit df69226 into main Dec 18, 2024
2 of 3 checks passed
@Romainhir Romainhir deleted the fix/delete-user-dependencies branch December 18, 2024 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix user delete to properly delete user's relations in the app

5 participants