Skip to content

02. Project and Layer Map

Why This Page Matters

Newcomers often understand architecture diagrams in the abstract but still struggle to answer a basic practical question:

Where should a change actually go?

This repo’s five projects give a clear answer. They are not decorative folders. They are the primary boundary mechanism for keeping UI, orchestration, simulation, and domain concepts from leaking into one another.

The Five Projects

The solution is split into:

  • InspectionPrototype.App
  • InspectionPrototype.Presentation
  • InspectionPrototype.Application
  • InspectionPrototype.Infrastructure
  • InspectionPrototype.Domain

These are consistent with the layer boundaries described in SLICE-001.

What Each Project Owns

InspectionPrototype.App

This project owns startup composition:

  • WPF application entry point
  • DI bootstrapping
  • host startup and shutdown
  • app-level configuration files such as appsettings.json

Relevant files:

  • src/InspectionPrototype.App/App.xaml.cs
  • src/InspectionPrototype.App/appsettings.json

Think of this project as the composition root, not the place where runtime behavior should accumulate.

InspectionPrototype.Presentation

This project owns UI projection:

  • view models
  • UI-facing collections and display strings
  • command wiring from UI actions to application services

Relevant file:

  • src/InspectionPrototype.Presentation/ViewModels/MainViewModel.cs

The important architectural rule is that presentation projects AppState; it does not orchestrate the workflow itself.

InspectionPrototype.Application

This is the most important project architecturally. It owns:

  • AppState
  • command guards
  • workflow orchestration
  • state transitions
  • runtime services such as telemetry and frame pipelines
  • application abstractions used by infrastructure

Relevant files:

  • src/InspectionPrototype.Application/State/AppState.cs
  • src/InspectionPrototype.Application/Services/WorkflowService.cs
  • src/InspectionPrototype.Application/Guards/CommandGuards.cs

If you are unsure where business or runtime logic belongs, it probably belongs here.

InspectionPrototype.Infrastructure

This project owns the “outside world” details:

  • simulator implementations
  • file-backed recipe catalog
  • file-backed run history store
  • fault injector implementation
  • configuration-backed simulator profile loading

The application layer should depend on abstractions, while infrastructure satisfies them.

InspectionPrototype.Domain

This project owns the stable contracts used everywhere else.

Examples:

  • Recipe
  • ScanPoint
  • Alarm
  • RunSummary
  • RunTerminalStatus

This project stays intentionally small so that the rest of the solution can share the same nouns without dragging in runtime orchestration details.

Actual Dependency Direction

The project references confirm the intended direction:

  • App references Presentation, Application, and Infrastructure
  • Presentation references Application and Domain
  • Application references Domain
  • Infrastructure references Application and Domain
  • Domain references nothing else in the repo

This is a healthy shape for the current design because:

  • domain remains the most reusable layer
  • application coordinates behavior without depending on UI
  • presentation can read domain/application contracts but not infrastructure internals
  • infrastructure can implement application abstractions without the UI reaching into it directly

Why This Design Was Chosen

This project structure supports the central-state-store decision from ADR-001.

If the app had only one project, it would be much easier for:

  • view models to own hidden mutable state
  • simulator details to leak into UI code
  • file access to bypass application rules
  • tests to become UI-heavy and brittle

The split projects make those mistakes more visible.

Trade-Offs

Benefits

  • clearer ownership
  • easier unit and service testing
  • easier code review because layer violations stand out
  • better fit for AI-assisted work because tasks can be assigned by boundary

Costs

  • more files and interfaces than a tiny demo would need
  • some boilerplate around DI and abstractions
  • a newcomer has to learn the repo map before editing confidently

That cost is worthwhile here because the repo doubles as a teaching system.

Practical Rule Of Thumb

Use these quick rules:

  • if it talks directly to WPF controls or display strings, it belongs in Presentation
  • if it decides whether a command is allowed or how workflow changes, it belongs in Application
  • if it reads files or simulates devices, it belongs in Infrastructure
  • if it is a stable business noun shared everywhere, it belongs in Domain
  • if it wires the app together, it belongs in App

Diagram Brief

  • Title: Project and layer dependency map
  • Purpose: Show the five projects, their responsibilities, and reference directions
  • Audience: newcomer developer preparing to make changes safely
  • Nodes: App, Presentation, Application, Infrastructure, Domain
  • Edges: App -> Presentation, App -> Application, App -> Infrastructure, Presentation -> Application, Presentation -> Domain, Application -> Domain, Infrastructure -> Application, Infrastructure -> Domain
  • Grouping: Composition root, UI projection, core orchestration, external adapters, shared contracts
  • Caption: The project structure is the first layer of enforcement for architectural intent
  • Destination file path: docs/diagrams/source/architecture-02-project-layer-map.drawio

Docs-first project memory for AI-assisted implementation.