If I can hand a piece of code off to someone on my team, give them a quick walkthrough, let them at it and not get a call immediately — I’ve commented my code correctly.
I’m in the business of building solutions for other companies and yes, I dislike the documentation part (and yes I dislike the diagramming part just as much, apparently a photo of a whiteboard just doesn’t cut it). As such, I try to minimize the amount of documentation I have to output by leaving it to high-level discussions on code (go to this file) and/or here is where all these configuration files reside.
When I look at code commenting, I generally like to think of it in two parts — Context and Usage.
Context
The Context is the why I have built something the way I have done it. This part is generally to help someone know how to and not to use the code in front of them — i.e., why did I go this route, what were the limitations of the API, why does the order of operations go this way. That sounds like a novel, but generally it ends up being a few lines, referencing other methods. I try to keep my contextual commenting to the classes and methods themselves unless there is something really wonky that I needed to do to make it work, i.e., “DON’T CHANGE THIS SETTING UNLESS YOU WANT TO HAVE A BUSY WEEKEND”.