Sometimes software just seems to happen haphazardly, despite our allegiance to diligence and process. Systems creep into our lives through some combination of people, skills, and tools. The result is often a mass of unfamiliar and unclear components written by many authors, with little understanding of the big picture.

Benefits of a Broad Awareness

Software, when managed well, benefits from a broad awareness of the "moving parts" in the ecosystem that surrounds its creation and consumption. Real people interact with the systems we build, and we should build better models to track and describe those systems.

Fragmented Functions and Isolated Teams

Many times teams dedicated to a specific function like Quality Assurance have applications and systems that allow management of entities directly relevant to their job function, BUT!… these teams don’t have a master system that ties together concerns across other teams and job functions. Neo4j can solve this with the right modeling in place.

Connecting the Concerns

By tracking the parts of a system, how they connect and interact, and who cares about those connections, we can better understand the impact of changes we make, the stakeholders concerned with and impacted by those changes, and, through visualization, we can anticipate and communicate these impacts.

About the model


In this model, the following categories have been adopted to group closely-related labels:

Node Domain

Labels included


:Audience, :Group, :Organization, :Person, :Role


:CheckIn, :Defect, :Feature, :Iteration, :Release, :Requirement, :Task, :TestCase, :TestSuite, :UserProfile, :UserStory


:AppLayer, :CodeProject, :CodeSolution, :Component, :CssFile, :Database, :DbFunction, :DbTable, :DbSchema, :DbView, :Environment, :File, :JsFile, :LocalizationKey, :Location, :MvcController, :MvcView, :Platform, :Permission, :Service, :Server


:Audience, :Document, :Term, :Publication, :Skill


:Defect, :Environment, :Feature, :Requirement, :TestCase, :TestSuite, :UserProfile, :UserStory


:CssFile, :JsFile, :MvcController, :MvcView


The "Human" Node Domain - People and Groups

Having a "map" of the human or organizational environment in which software is built allows us to navigate the challenge of finding answers to questions or fulfilling requests needed to change the system. It also assists our communication efforts when we need to inform stakeholders of impacts on their business processes.

// Find Node Types in the "Human" Node Domain
MATCH (m) WHERE m:Person OR m:Group OR m:Role OR m:Organization

The "Process" Node Domain - Tracking Work

In this example, labels included in the Process Node Domain through metadata are used to find instances of such kinds of nodes.

// Find node examples in the "Process" 'Node Domain'
MATCH (nt:NodeType)--(:NodeDomain { name: "Process" })
WITH COLLECT( AS processNodeTypes
MATCH (m) WHERE LENGTH(FILTER(lbl IN labels(m) WHERE lbl IN processNodeTypes)) > 0

Example: Find connected system elements

When preparing to make modifications to shared code assets in an application, it can be useful to visualize an asset’s connections to other parts of the system. For example, consider an e-commerce application that contains a shared stylesheet that affects multiple views in a Web interface. A Cypher query can reveal multiple dependencies on the code being modified.

Here’s an example of shared CSS files in a Web e-commerce application.

// CSS to MVC View and MVC Controllers, if present
MATCH (css:CssFile)--(vw:MvcView)
OPTIONAL MATCH (vw)--(ctl:MvcController)
RETURN css, vw, ctl;

Example: Modeling source code check-ins

As source code is checked in, it is helpful to trace back the source code updates to the assets and features they affect. In most systems, source control is a silo unto itself, not offering any tracing capability to abstract designations of functional areas within the applications. By modeling code commits in the graph, you can make connections not naturally supported by the tools we use on a regular basis.

// Developer checks in changes
MATCH (dev:Person { name: "Dev, Donna" })
MATCH (global_css:CssFile { name: "Global.css" })
MATCH (details_css:CssFile { name: "ProductDetails.css" })
MERGE (checkin:CheckIn { name: "Change set 2231" })
	ON CREATE SET checkin.description = "CSS fixes for product details"
MERGE (global_css)-[:INCLUDED_IN]->(checkin)
MERGE (details_css)-[:INCLUDED_IN]->(checkin)
MERGE (dev)-[:SUBMITTED { submitDate : "2015-06-13" }]->(checkin)
RETURN dev, global_css, details_css, checkin;

Example: What features were affected by a check-in?

By using a few "jumps" in a Cypher query, possible impacts on high-level features can be determined, and this information can be used to narrow the list of items on which to focus.

// What features did a checkin affect?
MATCH (checkin:CheckIn { name: "Change set 2231" })
MATCH (css_file)-[:INCLUDED_IN]->(checkin)
MATCH (css_file)--(vw:MvcView)
MATCH (vw)-[*1..3]-(feature:Feature)
RETURN DISTINCT checkin, css_file, vw, feature;

Example: What tests does QA need to run?

Going beyond Features affected, you can also use associations of Test Suites with Features and associations of Test Cases with Test Suites to build a list of test cases needed to be exercised for a given code check-in.

This can also be taken farther, factoring in Test Cases needed for a Release, based on the code associated with the Release (described later).

// Data: What tests does QA need to run?
MATCH (checkin:CheckIn { name: "Change set 2231"})
MATCH (css_file)-[:INCLUDED_IN]->(checkin)
MATCH (css_file)--(vw:MvcView)
MATCH (vw)-[*1..3]-(feature:Feature)
MATCH (t_case:TestCase)--(t_suite:TestSuite)-[*1..2]-(feature)
RETURN DISTINCT AS `Test Suite`, AS `Test Case`;

Example: Associate a check-in with a release

By associating Check-ins with Releases, you can enable a full analysis on the changes made for a release, including the Features impacted.

MATCH (checkin:CheckIn { name: "Change set 2231" })
MATCH (release { name: "Release v1.3" })
MERGE (checkin)-[:INCLUDED_IN]->(release)
RETURN checkin, release;

Example: What needs tested for this release?

Conclusions about what Test Cases to run for a Release can be gleaned from the model.

// Data: What needs tested for this release?
MATCH (rel:Release { name: "Release v1.3" })--(checkin:CheckIn)-[*1..4]-(feature:Feature)--(suite:TestSuite)--(testCase:TestCase)
RETURN DISTINCT AS `Release`, AS `Check-In`, AS `Test Suite`, AS `Test Case`;

Example: What’s scheduled for a given release?

In addition to projecting test needs for a Release, a high-level overview of the "contents" of a Release can be modeled.

// What's scheduled for Release v1.3?
MATCH (release_v1_3:Release { name : "Release v1.3" })
OPTIONAL MATCH (release_v1_3)<--(n)
RETURN release_v1_3, n;

Example: What’s in a given release (release notes from check-ins)

A raw view of Check-ins associated with a Release can allow release notes to be compiled and then published to stakeholders.

// Data: What's in release v1.3?
MATCH (rel_v1_3:Release { name: "Release v1.3" })
OPTIONAL MATCH (rel_v1_3)--(checkin:CheckIn)
RETURN AS `Release`, AS `Check-In`, COALESCE(checkin.description, "No description provided") AS `Description`;

Example: What release versions exist in each environment?

One challenge for software development teams is keeping track of versions by environment. If you have a limited number of environments to select, this is even more crucial to know.

Part 1: Add a release to the UAT environment

// Add v1.3 to UAT
MATCH (rel_v1_3:Release { name: "Release v1.3" })
MATCH (uat:Environment { name: "UAT Environment"})
MERGE (rel_v1_3)-[r_1_3:DEPLOYED_IN]->(uat)
RETURN uat, rel_v1_3, r_1_3;

Part 2: Check releases by environment

// Releases in environments
MATCH (rel:Release)--(env:Environment)
RETURN rel, env;
// Data: Releases in environments
MATCH (rel:Release)-[i]-(env:Environment)
RETURN AS `Version`, TYPE(i) AS `is`, AS `in Environment`;

Try it out

Execute some queries for yourself to explore the model descibed above.


By modeling the disparate parts of the software development process, a better understanding of risks and impacts can be visualized as software is being developed. This can prevent wasted time and effort fixing unanticipated problems that the model can reveal.

Created by Jeffrey A. Miller - Twitter | Blog | LinkedIn