What: Route handlers call db.* and docker_client.* directly and also do cross-cutting business logic (port-collision scans, state transitions, RCON+offline routing in server_players.py).
Why: Routes are hard to test in isolation, and the same business rule (e.g. port collision) is restated in multiple places.
Approach: Introduce a services/ package — server_service, membership_service, lifecycle_service. Each route handler becomes thin orchestration; rules live in services.
What: Route handlers call
db.*anddocker_client.*directly and also do cross-cutting business logic (port-collision scans, state transitions, RCON+offline routing inserver_players.py).Why: Routes are hard to test in isolation, and the same business rule (e.g. port collision) is restated in multiple places.
Approach: Introduce a
services/package —server_service,membership_service,lifecycle_service. Each route handler becomes thin orchestration; rules live in services.