CMDB - edmozley/freeitsm GitHub Wiki

CMDB

Folder: cmdb/ Colour: Magenta gradient

Configuration Management Database β€” model your IT estate as a graph of typed objects (servers, databases, applications, etc.) with a strict containment hierarchy and a separate user-defined relationships layer.

The original design rationale and roadmap lives at docs/cmdb.md in the main repo β€” read it for why the module is shaped this way, but note it is a pre-build design doc and this page is what the module actually does.

Developer guides: CMDB foundations (the data model and the rules you cannot break) Β· Impact analysis (how the blast radius is computed) Β· Data quality (the audit checks).

Browse Page (cmdb/)

Class sidebar with each class's object count β†’ table of objects in the selected class showing name, parent, child count, last updated. A name-filter search box at the top. + New creates an object inline and opens it for editing β€” for classes with required properties, the modal also collects those up front.

Object Detail Page (cmdb/object.php?id=X)

The page leads with what the item is and matters to, not with its fields.

Header

The class icon (from the icon assigned to the class), the name β€” click to edit, saves on Enter or blur β€” and a row of chips: the class, the item's signal value, whether it is in service or only planned (click to flip), its parent (click to change or detach), and a warning if nothing has touched it in over six months.

The header is coloured by the item's own data. A rail down the left takes its colour from a dropdown that says how much the thing matters β€” a field named for criticality or severity wins, otherwise any coloured dropdown, otherwise a value like Critical / High / Low. A critical production server and a decommissioned wall switch no longer render identically. Nothing to configure; it reads what you already recorded.

The two actions on the header are Generate summary and Open as diagram. Delete lives at the foot of the page.

The four numbers

Directly under the header, and clickable to jump to the relevant panel:

Number Means
things break if this fails the size of the blast radius
open tickets tickets currently referencing this item
connections everything attached, of every kind
days since anyone touched it turns amber past six months, matching the data-quality staleness rule

Details

Every property with a value, as cards. Empty fields collapse behind a single line β€” "2 fields are empty β€” show them" β€” instead of a row each saying (not set), with a completeness meter in the header. Type-aware inline editors:

Type Editor
text Single-line input
number Numeric input
date Date picker
boolean Yes-No select
dropdown Coloured pill dropdown (colours come from the property's option definitions)
object_ref Autocomplete picker scoped to the property's target class β€” renders the value as a clickable pink pill that navigates to the referenced object

Click any value to edit in place. Saves on Enter / blur. Escape cancels. Required-field validation server-side.

A βš™ cog appears on each card on hover, opening a floating draggable modal to edit the property's definition β€” label, key, type, dropdown options and colours, required, this is a dependency β€” without leaving the page. It edits the class, so the change applies to every object of that class.

Connections

One panel for everything attached to this item, replacing what used to be four: what points at it on the left, the item itself in the middle with its parent above and its descendants below, and what it points at on the right. Every entry carries its class icon and the verb that links it, so a row reads "is monitored by this" or "this connects to".

It opens with a count of each kind, and every figure is shown including the zeros β€” "none" and "we didn't look" are different answers, and only one of them is reassuring:

Kind How one is created
descendants from the child's page, by naming this item as its parent
relationships + Add, right there on the count
property links by filling in the field, in Details
parent + Set / Change, on the count

The counts are by kind rather than by direction precisely because each kind is created a different way β€” a single "add" button over a merged panel would imply it could make all four when it can only ever make one. Direction is still legible from the column headings and the verb on every row.

Descendants are counted all the way down, not just direct children, and anything deeper than one level says so.

Removing a relationship is the Γ— on the row, with a confirmation. There is deliberately no Γ— on a property link or a descendant: those are unlinked by clearing the field, or by re-parenting the child.

Adding a relationship β€” in either direction

The modal asks which way round before anything else: this object does it, or the other one does it. A preview spells out the exact sentence that will be stored, and how it reads from the far end:

SolarWinds Monitoring monitors SQLSVR01 Read from the other end: SQLSVR01 is monitored by SolarWinds Monitoring

Without this, a verb could only ever be recorded pointing away from the item you were looking at, so "something monitors this server" meant navigating to that something first.

Deleting

At the foot of the page, in its own bordered area rather than the header. The confirmation counts the whole subtree, not just direct children, because the delete cascades all the way down.

AI Summary

Pink-tinted card at the top of every detail page with a sparkle ✨ label. Click Generate (or Regenerate) to have Claude produce a 2-3 sentence prose synthesis covering class + hierarchy + owner + what depends on it.

Locked-down prompt β€” factual prose only, no speculation, no markdown, no bullets. Pulls the full context (properties with resolved object_ref names, parent, children, both directions of relationships, impact references). Cached on the row in ai_summary + ai_summary_generated_at so no AI call per page view.

"If this failed" β€” the blast radius

The panel opens with a headline ("4 other things would be affected, up to 2 steps away.") and then draws the failure as a chain running left to right: this object, then everything one step away, then everything two steps away. A server takes out the databases it contains, which take out the applications that depend on them, which take out the service your customers notice β€” and you read it in that order rather than reconstructing it from a list.

Every entry says how it was reached β€” "contained by SQLSVR01", "depends on FREEITSM", "Host Server points at SQLSVR01" β€” so a surprising entry can be traced rather than doubted.

Only edges you have said carry impact are followed. Otherwise the panel would report that a server failing affects the building it sits in. Three kinds of link feed it:

Link Carries impact when
Containment (parent β†’ children) Always β€” a child cannot outlive its parent here (the same rule that makes delete cascade)
Relationships The type is set to spread impact β€” see Relationship Types below
Object-reference properties The property is ticked as "This is a dependency" β€” for a Database whose Host Server points at a Server

Everything starts as doesn't spread impact, including on an existing install, so nothing appears until you configure it. If nothing is configured yet the panel says so explicitly rather than showing an empty list β€” "nothing depends on this" and "nothing is set up to spread impact" look identical otherwise, and they mean very different things.

Very large estates are capped, and when the cap bites the panel says the list is partial rather than presenting it as the whole answer. On a multi-company install the trace never leaves the company that owns the object.

Open as diagram

Open as diagram builds a Network Mapper diagram from the blast radius: the failed object at the centre, one ring per step outwards, connectors drawn along the impact path β€” solid for relationships, dashed for containment and property links, labelled with the verb.

It opens zoomed to fit, and from there it is an ordinary diagram: drag it into whatever shape you want, annotate it, version it, export it to PNG or PDF, attach it to a change or an incident review. The panel answers the question; the diagram is what you send to somebody.

The button only appears if you have access to Network Mapper.

Pure graph traversal β€” no AI required for the data β€” but the AI summary uses the same info to write its prose.

Everything attached to the object, impact-carrying or not, is in the Connections panel below. Impact, the mini-graph, the hierarchy and the relationship lists used to be four separate panels asking one question in four ways; on a sparsely-connected item that produced four separate empty states and said the same fact up to four times.

Data Quality (cmdb/audit.php)

A read-only health check, reached from Data quality in the module header. It reports how many objects it examined and what it found, one card per check.

Every check is shown even when it finds nothing. A clean check is information β€” and hiding it would leave you unable to tell a passing check from one that never ran.

Check What it means
Impact tracing is switched on If no relationship type or property carries a failure, every blast radius is empty however good the data is. This one makes the others moot, so it is listed first
Broken object references A property pointing at an object that no longer exists. The only check rated as an error β€” it is dangling data, not an omission
Required fields left empty The class says the property is required but the object has no value. Usually means the property was made required after those objects were created
Dependencies not filled in A property ticked "This is a dependency", left blank β€” a hole where a blast-radius link should be
Connected to nothing No parent, no children, no relationships, no references either way. Can never appear in anyone's blast radius, and nobody will reach it by navigating
Not touched in a while Nothing has updated it in six months β€” how a CMDB quietly stops matching reality

The checks are derived from declarations you have already made (a property marked required, a property ticked as a dependency, a relationship type set to carry impact). There is no rule builder and no new schema β€” the audit only reports where reality has drifted from what the install already says it wants.

Nothing here changes your data, and a finding is not automatically a mistake β€” plenty of things genuinely do stand alone. Long lists are capped, and the card says so rather than presenting a partial list as the whole answer. On a multi-company install you only ever see your current company's objects.

Settings (settings/)

Three tabs:

Classes

Define types of things (e.g. Server, Database, Application).

  • Each class has its own auto-generated immutable class_key plus an editable display name (so renaming labels never breaks references)
  • Click the property-count badge to manage that class's properties:
    • Property fields: label, immutable key, type (text / number / date / boolean / dropdown / object_ref), target class for object references, required flag, dropdown options, display order
    • Property keys are immutable β€” renaming labels is safe
  • Dropdown options use a row-based editor with per-option colours (click a swatch to set, Γ— to clear); colours render as tinted pills on the object detail page

Relationship Types

Define the verbs that link objects (e.g. depends on ↔ is depended on by). Three defaults seeded on first run: depends on, connects to, managed by.

AI Integration

The shared AI Providers panel (provider / model / key + Test connection) plus a custom-instructions textarea β€” pick Anthropic, OpenAI or OpenRouter. Kept as its own per-feature key (separate from Knowledge AI / Reply Cleanup / Forms / Workflows) for granular billing visibility.

AI Suggest Properties

Two-stage wizard in the Properties manager:

  1. Stage 1 β€” clarifying questions: Claude is given the class name + description + existing properties and asks 3-5 short questions about the analyst's specific environment (e.g. for Database: "What kind β€” SQL Server / Postgres / Mongo?", "Do you track schemas separately?")
  2. Stage 2 β€” suggestions: answers are sent back; Claude returns 6-12 property suggestions, each with label / immutable property_key / type / required-flag / one-line why rationale. Dropdown suggestions include generated option lists; object_ref suggestions include a target-class hint

Auto-creates missing target classes for object_ref suggestions β€” if Claude proposes Owner β†’ Person on a Database class but no Person class exists, the flow auto-creates the class with sensible defaults and points the property at it.

The analyst sees a checked-by-default list with the AI's reasoning visible inline, unticks anything unwanted, and clicks Add Selected β€” properties are bulk-created via the existing save_class_property.php endpoint.

Tickets ↔ CMDB Linking

Tickets get an Affected CMDB Objects section in the reading pane β€” type to search across every CMDB object, click to link, X to unlink. Each linked object renders as a clickable info card showing class + parent context.

The CMDB object detail page reciprocally gets an Activity panel below Details: open tickets (live) and recent closed tickets (capped at 20, total count shown) β€” each rendered as a card with status pill in the lookup colour, priority, assignee, department, and last-updated/closed date. Clicking any ticket card deep-links via tickets/?ticket_id=X.

The AI summary prompt also pulls open + closed ticket counts so the synthesis can mention things like "currently has 2 open tickets including a P1 backup failure" β€” turning the CMDB into a live operational map rather than a static inventory.

Planned Objects (Future-State Architecture)

A nullable boolean is_planned flag on cmdb_objects lets you record future-state architecture in the same CMDB as your real estate without forking the data. Toggle it in the New Object modal and on the object detail page header.

  • Planned objects render with a dashed border + amber PLANNED pill across every surface that shows the object β€” the browse table, the detail header, and search picker results
  • When the object goes live, toggle the flag off β€” a single column flip, no migration
  • The AI summary prompt is taught to surface planned status near the start of the synthesis and frame the sentence in future tense ("will host…", "is proposed to…") so the reader knows immediately the object isn't yet in service
  • Designed hand-in-hand with the Network Mapper, where planned nodes render in the same dashed-amber style β€” so a diagram can show as-is and to-be architecture side by side

Multi-company

On an install with more than one company (see Multi-tenancy), a configuration item belongs to exactly one company. The browse list, the search box and every picker (parent, relationship target, linked-object property) show only the company you're currently working in, and opening, editing or deleting a CI from another company reports it as not found β€” the app never confirms it exists.

There are no shared CIs. A client's servers, services and applications are entirely their own; there is no equivalent of the "shared with everyone" knowledge article. That one decision drives the rest:

  • a CI's parent, its relationships and any object_ref property must all point within the same company;
  • that rule binds staff with access to every company too. A permission check alone wouldn't stop them β€” they can legitimately reach both sides β€” and a cross-company link is a side channel even when the other CI is unreadable, because you can still confirm it exists and bind your own records to it;
  • linking a CI to a ticket checks both ends, and a CI's linked-tickets panel lists only same-company tickets.

What stays shared: classes, class properties, property options, relationship types and icons. They describe how you model your CMDB rather than whose equipment it is, so they remain install-wide admin config β€” the same call made for ticket statuses and priorities.

Not yet possible: moving a CI between companies. Tickets and changes have a move to company action; CMDB deliberately doesn't. A CI isn't a standalone row β€” it sits in a tree with relationships hanging off it, so a move must decide the fate of its parent, its children and every link, and either default is wrong (leave them and you create exactly the cross-company links the model forbids; take them and one click silently re-homes a whole subtree). For now a wrongly-filed CI is deleted and recreated. The shape this would take when built is sketched on the progress tracker.

On a single-company install none of this is visible β€” every CI simply belongs to your one company.

Data Model

8 tables, all prefixed cmdb_:

Table Purpose
cmdb_icons Curated icon lookup
cmdb_classes Class definitions
cmdb_class_properties Property definitions per class
cmdb_class_property_options Dropdown options (with optional colour)
cmdb_objects Object instances (incl. parent_id for the containment hierarchy)
cmdb_object_properties Property values per object
cmdb_relationship_types Verb definitions (verb + inverse)
cmdb_object_relationships Edges between objects

Plus ticket_cmdb_objects, which carries the ticket ↔ CI links described above.

Strict cascade-delete on parent_id (per the design's ontological dependency parent semantics β€” if the parent goes, the children go too). Cycle prevention on parent assignment walks up to 100 hops.

Help

Interactive help guide at cmdb/help.php with sticky scroll-spy navigation and 14 sections covering when to use the module, the five core concepts, classes & properties, AI Suggest Properties, adding objects, parent & children, relationships, the synthesis layer (AI summary / Impact / Map), linking tickets, data quality, the settings tour, companies, and tips & conventions.

Domains (3.0.0)

A CI's page has a Domains panel listing the domains it depends on, with each one's expiry and security grade - link and unlink them there, or from the domain's own Connections tab. It is shown only to analysts who can open Domains, and a CI can only be linked to a domain in the same company. See Domains β†’ Connections.