Code generation should be the "first-resort" pattern.
When talking code generation, it enforces you to think about your data model, your flow, patterns, usability, readability.
It is perfect to build repetitive boilerplate you can type on your own without thinking, so instead of taking up 10 minutes fighting input/UX bandwith of your hands and tools, you can generate huge chunks of code you would have to write anyways (and possibly make a mistake).
If I can make a model that has 50 lines and will generate 50 different classes, 50 files and 600 methods where I only need to fill out the expressions, that is writing code.
If I am going to say how it's all boilerplate and write it by hand, chances are I will have something nobody else will understand with bugs I cant remember or will have to rewrite the above by hand into a boiler-plate-like way again, which to me, makes no sense to do manually.
What I am for, as a programmer, is writing code to automate tasks that are determined by some input tasks to allow humans with brains to focus on things that need to thought.
To the extent some part of coding is such a determined task, automating it with code generation makes sense. Though there tends to be a lot of overlap between what is addressable by code generation and what is addressable by reusable libraries, and in most cases if both solve the same problem, I’d prefer a library to a generation template.