The Control Plane
Everything so far runs on its own — orchestrations loop, timers fire, queues drain. But
someone has to drive it: onboard a camera, change its rate, kick a stuck orchestration,
manage who can see what. That's Alert.CA.Admin.API — an ASP.NET Core Web API (hosting the
admin React SPA) that is the platform's control plane. The striking thing about it is what it
doesn't do: it never calls the engine directly.
The one idea to hold on to
The Admin API controls the engine indirectly, through shared state. To act on a camera it writes the intended state in Cosmos and lets the engine's change-feed trigger react; to observe a camera it reads the monitoring table. There is no RPC to the orchestrations.
"Kick this orchestration" is the cleanest example — it just bumps a timestamp:
// KickOrchestrationCommand
patchOperations.Add(PatchOperation.Set(nameof(AcquisitionDeviceEntity.LastUpdated), DateTimeOffset.UtcNow));
await _acquisitionDeviceRepository.PatchAsync(deviceId, patchOperations);
That Cosmos write is picked up by the engine's
change-feed redeploy. And to show a
camera's status, DurableEntityService reads GetLatestDurableEntityByDeviceId — the
monitoring row — never the running entity. Write intent to Cosmos, read status from the mirror:
that's the entire coupling between control plane and engine.
CQRS: thin controllers, handlers do the work
The API is split into two projects on the CQRS pattern. Alert.CA.Admin.API holds thin
controllers that translate HTTP into commands and queries; Alert.CA.Admin.API.Application
holds the MediatR handlers that actually do the work:
Every request flows through a MediatR AuditBehavior pipeline, so administrative actions are
audited by construction rather than by remembering to log each one.
Because the Admin API acts by writing Cosmos and letting the change feed react, a "kick" or a config change returns success once the write lands — not once the orchestration has redeployed. There's a small propagation delay, and if the device is inactive or in another environment the engine skips it entirely (per the redeploy gating). Success from the API means "intent recorded," not "engine already reconfigured."
Wrapping up
The Admin API is a CQRS ASP.NET Core control plane that drives the platform entirely through shared state — writing intended config to Cosmos (where the change feed turns it into a redeploy) and reading status from the monitoring mirror — with Entra/API-key auth and an audit pipeline on every action. It's powerful precisely because it stays decoupled from the engine's runtime.
The rest of this section walks the control surface, starting with the one it exists for — driving the engine. Next: Controlling the Engine.