There is a massive temptation to look at classes for similarities in order to extract shared base classes or traits. Sometimes this makes sense and can be beneficial to the code base. Sometimes it does not.
More often than not striving to get rid of this “duplicate code” is done prematurely or done when it doesn’t make as much sense to share code. It complicates the codebase and makes it harder to change the newly merged concepts independent of each other.
Look at the meaning behind the classes and their data. If it makes sense for them to be separate classes to begin with that is a good indicator that code sharing may not be needed.
Write several “similar” classes or workflows before you start abstracting them. Things may not be as similar as they looked from the outside.