Product
Domain Driven Design
Domain-Driven Design with AI
How to Do DDD with AI and Qlerify

Insights from Virtual DDD Meetup

At a recent Virtual DDD Meetup, Staffan showcased how Qlerify accelerates domain modeling using AI.

From a simple text prompt, AI generated a CRM process featuring roles such as Salesperson and Sales Manager. The tool automatically generated domain events, placed them on a timeline, and mapped out commands and entities. The workflow was then turned into a Domain Model with Bounded Contexts, from which working API code could be produced.

The session sparked engaging discussions, including a surprise appearance by Eric Evans, the father of Domain-Driven Design (DDD), who asked insightful questions about the tool and its approach.

In this article we'll expand on the video with detailed step-by-step instructions you can follow. Whether you’re an architect, a domain expert, or a developer, Qlerify provides an intuitive and collaborative way to define bounded contexts, aggregates, and commands—helping you accelerate domain modeling and implementation.

Domain-Driven Design

DDD helps teams build software that closely aligns with business needs by structuring code around real-world business concepts. A common challenge, however, is that creating effective domain models takes time and expertise. That’s where AI-assisted modeling, as demonstrated in Qlerify, becomes an exciting innovation.

Getting Started with Qlerify for DDD

To follow along, log in to Qlerify or sign up for an account using the link in the footer. Once logged in, create a new project, start a blank workflow, and follow this walkthrough.

Note: This guide focuses specifically on AI-assisted domain modeling. For a more comprehensive introduction to Qlerify’s features, including EventStorming, see the EventStorming walkthrough (linked in the footer).

Step 1: Review Card Types

Before you begin, make sure you have created a new blank workflow and have an empty canvas in front of you. In an empty swim lane, you should see two buttons: “Add start point” and “Generate workflow with AI”.

Next, open Workflow Settings by clicking the cogwheel icon above the empty diagram. Navigate to the Cards tab to review the Card Type Settings:

  • Use AI: Under this heading, verify that Command and Aggregate Root are selected. Additional card types are optional.
  • Command: Under this heading, ensure that the Command card type is selected.
  • Aggregate Root: Under this heading, confirm that the Aggregate Root card type is selected.

Step 2: Generate with AI

If you want to change the LLM (Large Language Model), you can do so in Workflow Settings → AI. In this example, we use ChatGPT-4o.

If your workflow is empty, the “Generate Workflow with AI” button will be visible. Click this button and enter the following prompt (or use your own):

  • "A CRM process used by Sales Force"

Next, ensure that “Generate Data Models with AI” is checked, then click “Generate Workflow”. The process may take a few minutes to complete.

Once the process is complete, the LLM will have generated Domain Events, Cards, and Write Models. The Domain Events are placed on a timeline, distributed across swim lanes. Your workflow should resemble the example below, though variations may occur. In the following steps, we will continue using AI to generate Entities, Read Models, and, finally, API code.

Step 3: Generate Entities

At this point, the AI has already suggested entity names in free text and placed them on Aggregate Root cards.

But Qlerify goes beyond that. It can generate Entity definitions, including data fields with information about primary keys, relationships, and example data. Once entities are defined, you can replace the free-text entity names (on Aggregate Root cards) with links to Entity Definitions. The special card type "Aggregate Root" can contain either free text or a direct link to an Entity (clickable combo box).

If you already have an existing data store, you can begin by importing your entity definitions before generating your workflow diagram. The workflow can then be generated strictly based on your existing database—or more loosely, allowing for flexibility. However, in this example, we’ll generate entity objects after creating the workflow.

Now, let’s generate the entities. The generated entities will be based on the free-text names on Aggregate Root cards. You can review and update them before moving on.

Steps to Generate Entities:

  1. Navigate to the Entities tab under the workflow diagram.
  2. Click + Entity, leave the description blank, and press "Add."
  3. Qlerify will generate entities using AI, based on the Aggregate Root names.

Now, you will get entities similar to these:

Step 4: Connect Entities to Your Domain Model

This step can be skipped and done while you are reviewing the write models (next step). However, if you have many commands operating on the same aggregate roots, you can save time by doing the following:

  1. Navigate to the Domain Model tab.
  2. Start from the top of the domain model and select Aggregate Root in each yellow box. If there is no matching entity you can click on "Create a new entity with AI".
  1. When there are multiple commands (and events) grouped around one aggregate root, all of them will be updated by the previous operation. If you only want to change the aggregate root for a single command to remove it from its group, select the event, open the sidebar, and change the aggregate root in the sidebar.

Step 5: Review the Write Models

Now it’s time to walk through the Write Model of each event, reviewing them step by step. Click on the first event, “Created lead”, then open the Data Models tab below the diagram. You should see a table named “Write Model” with blue headings for Input Data.

For each event, review and update the following parts of the Write Model:

  1. Command - The name of the action being performed.
    • Ensure the command name is clear and accurate.
    • Note: If this event does not represent a state-changing action, consider leaving it out for now by deleting it. If the step represents an important view without a state change, you can define a read model instead (covered in a later step). If the command translates into multiple commands across different aggregates, consider splitting it up or modeling it as a service object (discussed in the final step of this tutorial).
  2. Aggregate Root - The main entity that the command is operating on.
    • If not already linked to an entity, click the yellow box and select the correct entity from the list (either at the top of the table or below the table in the diagram).
    • If an entity is missing, you can generate it using AI.
  3. Input Data - The input data captured by the actor
    • Review the Input Data in both the table and the sidebar mockup. Add missing fields, remove unnecessary fields, or reorder fields (drag & drop on the table headings).
    • Related entities: If an input field belongs to a related entity, select the related entity in the row under the blue Input Headings.
  4. Sample Data - If possible, use realistic sample data that can be used later for testing.
  5. Update Entity - If you need to add, update, remove, or change the order of fields on the entity, use the pen icon that appears when hovering over the entity.
Aggregate Boundaries – While not explicitly shown yet (an upcoming feature), the aggregate boundary can be derived from the input data fields. If a command contains non-ID arguments for related entities, those entities should typically be within the aggregate boundary. As a result, the aggregate boundary is dynamic and can depend on the command.

Step 6: Read Models

Now, go through the workflow again from start to finish and identify where an actor needs to be provided with a specific view of data before invoking a command. For example, for the Sales Manager to approve an opportunity, certain data must be provided to support the decision.

Think of a Read Model as a query that retrieves relevant data for the user.
Note: In Qlerify, each event can have both a write model and a read model (or many read models in an upcoming release). From the perspective of the selected event, the read model should be seen as being consumed before invoking the command. (This is probably more inline with Event Storming than Event Modeling. The reason behind this choice is that it allows us to always center the Read and Write Model around the same actor.)

Select an event, such as "Approved opportunity by Sales Manager," and click on "+Write Model." Then, proceed with the option "From Workflow with AI." After the Read Model has been created, follow these steps:

  1. Query Name – Ensure the query has a clear, descriptive name (e.g., "Get Active Leads"). (This is an upcoming feature; currently, the command name will be displayed.)
  2. Main Entity – Assign a main entity, which serves as the starting point of the query.
  3. Description – Provide a natural language explanation of the query, including inputs, filters, aggregations, calculations, or business logic. (This is an upcoming feature.)
  4. Fields – A list of field names with example data.
    • Each field can be connected to a related entity. When you connect a field to a related entity, the related entity will be displayed in the Entity Relationship Diagram under the query. This helps analyze the query.
    • If no related entity is defined, the field should either:
      • Belong to the main entity, or
      • Be a calculated field.

By defining Read Models, you can ensure that actors have access the right data before invoking commands, making the system more user-friendly and efficient.

Work in progress: The Read Model will be developed in upcoming releases to better model different scenarios. The Read Model is not yet displayed in the domain model, which is another upcoming feature. It will also be possible to define queries as an API call to an external service (such as an LLM) to retrieve data needed for a command.

Step 7: Bounded Contexts

Now, navigate to the Domain Model tab under the workflow diagram and assign a Bounded Context to each Aggregate Root.

In the Domain Model, you will see:

  • All aggregate roots grouped by bounded context.
  • All commands grouped by aggregate root.
  • One Context Map per Bounded Context: When viewing a single bounded context, you can see all integration points that this bounded context has with other bounded contexts. Integration points are displayed with gray labels and the text "Integration with other bounded contexts." While this representation is somewhat simplistic compared to traditional context maps, it serves as a straightforward way to display all integrations for one bounded context at a time.
Defining bounded contexts helps divide the system into manageable, independent parts to clarify scope and ownership.
Note: In the current version, we do not display the Read Models in the Domain Model. This is a prioritized feature that will soon be released.

Step 8: Generating API Code

You have now defined a Domain Model including domain events, entities, read models, commands, roles, and bounded contexts. The domain model serves as powerful system documentation and a foundation for development, provided that you have correctly aligned it with your domain logic. We recommend that you iterate over the domain model and keep it as up to date as the current system documentation.

If you are planning to use the domain model for code generation, one of the most exciting steps remains. Based on the work you have done in this walkthrough, Qlerify can automatically generate API definitions and code. This is done per bounded context. This final step is described in detail in the AI Generate Code article. A link to the article can be found in the footer.

Takeaways from Eric Evans’ Discussion

Eric Evans, the creator of DDD, joined the discussion and raised thought-provoking questions. Key takeaways included:

  • AI-generated models serve as a powerful starting point but require iterative refinement.
  • There is potential for “round-trip engineering,” where updates to the codebase reflect back into the domain model.
  • While generic subdomains work well with AI, core domains require more human involvement to capture complex business logic

Get Involved & Try Qlerify

To explore Qlerify and see how it can enhance your domain modeling process, sign up and start modeling today! Use the sign up link in the footer of this page.

Watch the full Virtual DDD Meetup session: YouTube Video