Skip to content

Tags and Groups

Purpose

Tags and groups provide flexible classification and collection mechanisms.

They are intentionally separate concepts.

Tags

Tags are labels assigned to entities.

Examples:

text
Critical
Commissioned
Blocked
Trend
Production
Remote Access Ready

Tags are good for:

  • filtering,
  • visual labels,
  • simple classification,
  • workflow state where a full workflow engine is unnecessary,
  • reporting facets.

Tag Groups

Tag groups organize tags into sets.

Examples:

text
Criticality
├── Low
├── Medium
└── High
text
Commissioning Status
├── Not Started
├── In Progress
├── Blocked
└── Complete
text
Vendor
├── Trend
├── Siemens
├── Schneider
└── Tridium

Single-Select vs Multi-Select

Tag groups should support a selection mode.

text
single
multi

Single-select example:

text
Criticality = High

Multi-select example:

text
Asset Capabilities = BACnet, Modbus, Remote Access Ready

For single-select groups, the service layer must ensure only one active tag assignment exists per entity for that group.

Tags Are Entities

A tag should own an entity.

This enables:

  • audit,
  • permissions,
  • hierarchy placement if needed,
  • group membership if needed,
  • relationships if needed.

Tag-specific fields live in the tags table.

Entity Tags

Use entity_tags for tag assignment.

Recommended fields:

text
id
entity_id
tag_entity_id
created_at
deleted_at

Unique active assignment:

sql
CREATE UNIQUE INDEX uq_entity_tags_active
ON entity_tags(entity_id, tag_entity_id)
WHERE deleted_at IS NULL;

Entity Groups

An entity group is a named collection of entities.

Groups are useful when the user wants to manage a set of objects that are not necessarily in the same hierarchy branch.

Examples:

text
Commissioning Batch - July 2026
Critical BMS Controllers
Sites Requiring VPN Upgrade
Assets For Firmware Update

A group is itself an entity, with group-specific metadata in entity_groups.

Group Membership

Use entity_group_members to store membership.

Recommended fields:

text
id
group_entity_id
member_entity_id
created_at
deleted_at

Unique active membership:

sql
CREATE UNIQUE INDEX uq_entity_group_members_active
ON entity_group_members(group_entity_id, member_entity_id)
WHERE deleted_at IS NULL;

Groups Are Not Hierarchy

Do not model group membership with parent_entity_id.

Bad:

text
Commissioning Batch
└── Asset A

if Asset A is physically located under:

text
Customer -> Site -> Building

An entity should have one structural parent. Groups are many-to-many collections.

Tag Groups vs Entity Groups

ConceptPurposeExample
Tag GroupOrganizes labelsCriticality: Low, Medium, High
TagLabel assigned to entityHigh
Entity GroupCollection of entitiesJuly Commissioning Batch
Group MemberEntity in a collectionAsset A in July Commissioning Batch

User Experience

Tags should feel lightweight.

Groups should feel like user-manageable collections.

Examples:

  • user filters assets by tags,
  • user creates a group for a commissioning batch,
  • user bulk assigns assets to a group,
  • user opens group detail page to see members,
  • user applies batch actions to group members.

Backend Rules

Tag assignment must enforce:

  • root entity scope,
  • tag visibility,
  • selection mode rules,
  • soft-delete rules,
  • audit where needed.

Group membership must enforce:

  • root entity scope for group,
  • root entity scope for member,
  • whether mixed types are allowed,
  • whether member type is allowed,
  • duplicate prevention.

Example: Commissioning Batch

Entity type:

text
group

Group metadata:

json
{
  "name": "July 2026 Commissioning Batch",
  "allowsMixedTypes": false
}

Members:

text
Asset A
Asset B
Asset C

Actions:

  • assign commissioning status,
  • export list,
  • bulk update property,
  • create report,
  • review blockers.