Architecture, Technical Leadership & Governance
This example is the EnterpriseOps Command Center baseline that every later module of the course builds on: the
folder-per-layer solution structure, ADR-001, and the designable CommandCenterDashboard that reads its KPIs from
EnterpriseOps.Services through a one-line handler.
Nothing here is deployed anywhere. In-memory data only — no database, no network, no cloud account.
Run it
cd "LearnWisej-Samples/Enterprise Wisej.NET Course/Module 1/EnterpriseOps"
dotnet run -f net10.0 --urls http://localhost:5201
Then open http://localhost:5201. (Visual Studio: open EnterpriseOps.slnx, press F5 — the launch profile is
already on 5201.) The project multi-targets net10.0-windows;net10.0, so dotnet run needs -f.
What to try
| Control | What you should see |
|---|---|
| (on load) | The three KPI tiles (Open incidents · SLA at risk · Deployments today) fill in, dgvIncidents lists the contoso incidents, and the dark status bar reads Loaded 12 incidents — EnterpriseOps.Services.Workflow · NN ms. Signed in: ana.ops · Manager sits next to Refresh |
⟳ Refresh (btnRefresh) | The workflow pulls the operations feed: INC-1042 turns mitigated and is painted green, Open incidents drops to 11, status bar Refreshed — INC-1042 mitigated — EnterpriseOps.Services.Workflow · NN ms. Click again for the next scripted batch |
Failure paths are handled in the normal UI: a policy denial (DashboardPolicy, Technicians may not open the
Command Center) shows an amber banner and leaves the data untouched; an exception from the feed or the store is
logged with the correlation id and the user sees a red banner with a generic message plus (ref <id>). The
governance failure path — a 74-line handler with no service call — is caught by the review gate
(ReviewGate.CheckEventHandler), with Architecture/Samples/OrderEntryLegacy.cs.txt as the counter-example.
Where things live
Module 1/
├─ EnterpriseOps.slnx
└─ EnterpriseOps/
├─ Program.cs session composition root: SessionContext → Application.MainPage
├─ Startup.cs · Default.json · Default.html · Web.config · Properties/launchSettings.json (5201)
├─ UI/ CommandCenterDashboard.cs + .Designer.cs ← UI state only
├─ Controls/ KpiTile.cs + .Designer.cs ← shared designable control
├─ Domain/ WorkOrder · WorkOrderStatus · Priority · Tenant
├─ Services/ SessionContext · CommandContext · CommandResult
│ └─ Workflow/ DashboardWorkflow · DashboardResult (DashboardKpis, IncidentRow)
├─ Data/ IWorkOrderRepository · InMemoryWorkOrderRepository · SeedData
├─ Integrations/ OperationsFeed · ReleaseCalendar
├─ Security/ UserIdentity · UserRole · DashboardPolicy
├─ Diagnostics/ ActivityTrace (server log) · ErrorLog
├─ Resources/ UiText
├─ Architecture/ ADR-001-SolutionStructure.md · ArchitectureGovernancePatterns.cs (ReviewGate)
│ Samples/OrderEntryLegacy.cs.txt
├─ Deployment/ README.md — what lands here and in which module
└─ docs/ the five deliverables above
Production readiness — state, security, behaviour
State ownership. UI state (text, colour, Enabled, Visible, the grid's DataSource) belongs to the screen.
Session state (tenant, signed-in user, the current command and its correlation id) belongs to SessionContext,
created in Program.Main and stored in Application.Session.Context — one per browser session, never a static.
Business state belongs to Data/, reachable only through IWorkOrderRepository.
Security implications. Every permission decision is Security/DashboardPolicy, called by the workflow before
any integration or query. Every repository query is scoped to a tenant inside the repository. What the user reads
is Resources/UiText; exception details never leave ErrorLog.
Production behaviour. Every action mints a correlation id carried through result and log. Refresh is disabled
during a command and restored in finally; after each await, Application.Update(this) pushes the changes.
Known debt (T-1): the screen constructor is the composition root until Module 3's per-session registry.