A modular monolith deploys one application while preserving strong internal boundaries. It is the best default for SupportDesk AI because transactions, refactoring, testing, and operations remain simple. Domain and application code point inward; FastAPI, PostgreSQL, Redis, queues, and model providers remain replaceable outer adapters connected at one composition root.
Modules follow capabilities, then separate inward logic from adapters. A repository port uses application language:
The application service depends on these protocols. SQLAlchemy and a provider SDK implement them outside. main.py wires real implementations; tests wire fakes.
A route parses trusted framework inputs, invokes one use case, maps the result, and chooses HTTP semantics. It does not build prompts, perform SQL, authorize by scattered if statements, or commit transactions.
Look for independent scaling needs, security isolation, fault isolation, release ownership, regulatory boundaries, or a stable capability used through a clear contract. “The folder is large” is not sufficient. Extraction replaces local calls with networks, partial failures, duplicated data, and distributed operations.
AI libraries churn quickly. A model gateway port protects domain and application logic from provider response types. Prompt templates and output schemas may live with the AI feature, while execution adapters own provider-specific serialization, retries, and telemetry.
Move ticket creation into an application service using a repository protocol and unit of work. Provide an in-memory fake and SQL adapter.
Acceptance criteria: the same use-case tests pass against the fake and an integration database; application modules import no FastAPI, SQLAlchemy, Redis, or model SDK.