Areas and objects
Areas and objects describe the stable structure of the product domain. Their job is not to reproduce database tables; it is to identify business boundaries and concepts the rest of the model can reference.
An area groups concepts that share language and responsibility. Internally, modelARch connects problem-space subdomains with solution-space bounded contexts.
Use a separate area when:
- the same word has a different meaning in each context;
- one capability can change independently of another;
- responsibility or ownership is materially different;
- integrations or release topology need a clear boundary.
Do not create an area merely for every menu item or technical layer. “API,” “database,” and “frontend” are not business areas.
Relationships between areas should emerge from real model connections—events, commands, shared types, and integrations—rather than an isolated diagram that can drift.
Objects and aggregates
Section titled “Objects and aggregates”An object represents a business concept with identity, data, and behavior. An aggregate is its consistency boundary: changes inside it are coordinated through the root.
Examples:
Appointmentowns its lifecycle and scheduling invariants.Ordercoordinates its line items and total.WorkspaceMembershiprepresents who participates in a workspace and with which role.
Avoid modeling every noun as an independent aggregate. A line item that only exists inside an order may be an internal entity; a postal address may be a value object with no independent identity.
Fields
Section titled “Fields”A field has a name, type, requiredness, and optional constraints. It can also carry semantic meaning used by downstream projections, such as identity, money, date, status, media, or reference.
Useful questions:
- Does this value have its own lifecycle or only describe the object?
- Is absence meaningful, or should the field be required?
- Is the value constrained by an enum or a richer value object?
- Does a reference cross an aggregate boundary?
- Which action supplies a required value during creation?
Field names are not access control. A patientId field only creates a relationship; a query or command still needs a scope declaring how the current actor may reach the row.
Value objects and enums
Section titled “Value objects and enums”Use a value object for a group of values defined by meaning rather than identity, such as money, date range, or address. Use an enum for a closed catalog of named values whose meaning is part of the product.
Avoid encoding lifecycle states as arbitrary strings. A declared enum plus a state machine allows validation, transition-specific actions, UI affordances, and tests to agree.
Internal and external references
Section titled “Internal and external references”References within an aggregate can preserve its invariant boundary. Cross-aggregate references should normally identify the other root rather than embed its mutable state.
Cross-area behavior should be explicit through commands, events, reactions, queries, or integration ports. Direct hidden coupling makes regeneration and validation less reliable.
Naming
Section titled “Naming”Keep a code-safe canonical name and, where needed, a localized display label and natural plural. This lets generated identifiers remain stable without forcing English grammar into user-facing copy.
Next, connect structure to behavior with Actions, events, and rules.
