Skip to content

03. Domain Model ​

Why This Page Matters ​

A training repo becomes much easier to understand when the learner can separate stable domain nouns from runtime coordination logic.

The domain model in this project is intentionally compact. That is a strength. It gives the rest of the system a shared vocabulary without hiding workflow behavior inside giant “smart” entity classes.

The Core Domain Contracts ​

The InspectionPrototype.Domain project holds the primary nouns the rest of the repo shares:

  • Recipe
  • ScanPoint
  • Frame
  • InspectionResult
  • Alarm
  • RunSummary
  • RunTerminalStatus

These types are simple records, not large inheritance hierarchies.

Relevant files:

  • src/InspectionPrototype.Domain/Contracts/Recipe.cs
  • src/InspectionPrototype.Domain/Contracts/ScanPoint.cs
  • src/InspectionPrototype.Domain/Contracts/Alarm.cs
  • src/InspectionPrototype.Domain/Contracts/RunSummary.cs

How The Domain Is Used ​

Recipe And ScanPoint ​

Recipe defines the ordered scan plan:

  • a RecipeId
  • a name
  • an ordered list of ScanPoint entries

That ordered nature matters because the workflow processes points sequentially during a run. The recipe is not just configuration data; it shapes the runtime path.

Alarm ​

Alarm is a good example of a domain object staying focused while still carrying operational meaning.

It includes:

  • alarm code
  • severity
  • message
  • whether acknowledgment is required
  • whether the alarm is active
  • whether the operator has acknowledged it

This is enough to teach the difference between:

  • active unsafe condition
  • operator awareness
  • later clearance and recovery handled by application logic

RunSummary ​

RunSummary is the durable story of a finished run.

It includes:

  • identity
  • recipe name
  • start and end times
  • terminal status
  • defect count
  • major alarms
  • richer slice-4 metrics such as point counts, profile name, and defect breakdowns

That makes it suitable for both the “last run” view and the persisted history list.

Why The Domain Is Small ​

This repo does not try to make the domain layer own everything.

That is a deliberate design choice.

The application layer owns:

  • workflow state transitions
  • command guards
  • orchestration
  • fault recovery semantics

The domain layer owns the stable nouns and outcomes.

This is a good fit because the repo is simulating an industrial workstation, not implementing a full DDD-heavy enterprise model with rich aggregates everywhere.

The Real Runtime Model Lives Partly In Application State ​

One subtle but important architectural detail is that some important runtime concepts are not pure domain contracts. They live in InspectionPrototype.Application.State.

Examples:

  • AppState
  • ActiveRunState
  • WorkflowState
  • SafetySignals
  • DiagnosticsEntry
  • SimulatorProfile

That split is healthy:

  • domain contracts describe business objects and durable outcomes
  • application state describes the live runtime snapshot needed to coordinate the workstation

Trade-Offs ​

Benefits ​

  • the domain stays easy to read
  • stable contracts are shared cleanly across layers
  • runtime behavior remains explicit in orchestration code rather than hidden in rich entity methods

Costs ​

  • the learner must understand both domain contracts and application state
  • some concepts such as active-run metrics are represented outside the domain project

That trade is sensible for a training-oriented workstation app. It makes runtime control logic easier to inspect.

Where To Look In Code Next ​

After reading this page:

  1. read Recipe.cs, Alarm.cs, and RunSummary.cs
  2. compare them with ActiveRunState.cs and AppState.cs
  3. notice how terminal run information becomes more durable and compact than active-run information

That transition from live state to durable summary is one of the most teachable design moves in the repo.

Diagram Brief ​

  • Title: Domain model and runtime-adjacent state
  • Purpose: Show the most important domain contracts and how they relate to application-side runtime state
  • Audience: newcomer developer learning the system vocabulary
  • Nodes: Recipe, ScanPoint, InspectionResult, Alarm, RunSummary, RunTerminalStatus, ActiveRunState, AppState
  • Edges: Recipe contains ScanPoints; AppState references LoadedRecipe, ActiveRunState, ActiveAlarms, LastRunSummary, RunHistory; ActiveRunState evolves into RunSummary at terminal completion; RunSummary uses RunTerminalStatus
  • Grouping: Domain contracts, application runtime state, terminal outcomes
  • Caption: The repo keeps domain nouns small and stable, while live orchestration state stays in the application layer
  • Destination file path: docs/diagrams/source/architecture-03-domain-model.drawio

Docs-first project memory for AI-assisted implementation.