Skip to content

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

DirectoryPurpose
src/app/apiHTTP API routers for admin APIs, client APIs, and internal EMQX callbacks.
src/app/coreSettings, auth, security, and middleware.
src/app/dataSQLAlchemy schema, database connection, and repository composition.
src/app/domainDomain models and protocol parameter generation.
src/app/eventsSSE event publishing.
src/app/infrastructureExternal integrations such as the EMQX management API.
src/app/mcpMCP server, resources, tools, permissions, and audit.
src/app/projectionsPage and system status projections.
src/app/servicesBusiness use cases.
src/app/schemasPydantic 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.