A workflow engine that owns the state
The domain layer checks roles, request fields and permitted transitions. Record changes happen in database transactions; asynchronous model calls run outside those transactions. A model response cannot directly change an approval state.