Put most code in class libraries so new hosts (API, worker, AI, mobile) plug in without duplicating rules. Controllers should stay thin; fat controllers make reuse and testing expensive.
Business rules and workflows live in class libraries. Entry points are thin shells that connect those libraries to HTTP, queues, schedules, chat, etc.