There's a certain amount of disciplined duplication that you have to adopt as well. I think this hangs a lot of people up and failure to do it right leads to the complications you're discussing.
Adding a todo note, marking it done, editing it, and deleting it are all different use cases and each have thier own package and classes. However, most people want to have some kind of single ToDoNote class which is the "To Do Note". Doing that means they have to decide which package to put it in and then pull it in everywhere else. And then "common" logic starts piling up and features depend on crap from other features and accidental complexity starts creeping in. Now you've got a single ToDoNote class that has different sets of properties null or pipulated depending on where it was instantiated and what use case its being fed to, all requiring the programmer to keep this in their head instead of getting the compiler to help.
The reality is that the set of data you need to create a todo note is different from the data you need to edit it which is different from that which you need to delete it. They share common elements, but never at the same time. The solution is to create "NewToDo", "EditedToDo", and "DeleteToDo" models that for each feature. Sure, some of the models will share a "title" property (new and edit), and some will share an "id" property (edit and delete) but never all at the same time. This offloads this complexity from the programmer to the compiler and speeds up development.
You already know youre operating at the lowest of the low leves of excellence if you rely on monkey see monkey do code standards. Having low complexity code with minimal programmer brain space needed to operate in is how you level up to higher levels.