Backend
The backend uses FastAPI. It provides business APIs, MCP, SSE, snapshots, database access, EMQX synchronization, and client binding.
Before changing backend code, check the dependency direction in Project Structure. Stable HTTP behavior is defined by API Contract and API Reference.
Main Directories
| Directory | Purpose |
|---|---|
src/app/api | HTTP API routers for admin APIs, client APIs, and internal EMQX callbacks. |
src/app/core | Settings, auth, security, and middleware. |
src/app/data | SQLAlchemy schema, database connection, and repository composition. |
src/app/domain | Domain models and protocol parameter generation. |
src/app/events | SSE event publishing. |
src/app/infrastructure | External integrations such as the EMQX management API. |
src/app/mcp | MCP server, resources, tools, permissions, and audit. |
src/app/projections | Page and system status projections. |
src/app/services | Business use cases. |
src/app/schemas | Pydantic request and response models. |
Layers
Routers handle auth dependencies, request parsing, HTTP boundaries, and calls into services.
Services coordinate business use cases, repositories, events, EMQX, downloads, snapshots, and MCP behavior.
Repositories handle SQL reads, writes, conversion, and transaction boundaries.
Projections build frontend-facing shapes such as home status, config overview, node workspace, and system status.
If a page needs complex derived state, add a backend projection instead of duplicating rules in the frontend.
Typical projections include config overview, mesh workspace, endpoint control status, and system status. For related page behavior, see Frontend, Events, and Data Model.
State Rule
The database is the source of truth. Runtime state, client state, MQTT credentials, port forwarding rules, MCP tokens, and settings should all be represented in the database.
EMQX is an execution layer. If it is offline, write to the database first and synchronize when it comes back.
When MQTT credentials, online state, or EMQX callbacks change, update MQTT Protocol, MQTT Messages, and Client Lifecycle.
Errors
Business errors use the unified error structure. New error codes must be added to Errors.
Do not expose raw Python, database, or third-party exceptions to the frontend.
Realtime
After a write operation affects UI state, publish an SSE event. Payloads must be JSON serializable.
Event names, payloads, and frontend refresh rules are covered by Events and Realtime Reference.
Tests
Backend tests should cover API behavior, repositories, migrations, snapshots, EMQX offline recovery, MCP permissions, confirmations, and audit.
