- 10 minutes to read
Change Tracking and Audit Trail
This spoke covers the change tracking system and audit trail for Mapify's multi-user collaboration, answering who changed what, when, and why. For the full overview, see the Multi-User Collaboration hub.
Why Change Tracking?
| Benefit | Description |
|---|---|
| Compliance audit support | SOX, GDPR, HIPAA require "who changed what" audit trails |
| Root-cause analysis | Trace configuration changes that caused incidents |
| Accountability | Clear ownership prevents finger-pointing during outages |
| Rollback capability | Restore previous configurations if changes cause issues |
| Trend analysis | Identify frequently changed entities (instability hotspots) |
| Knowledge retention | Understand historical decisions when original team members leave |
Note: Change tracking is enabled by default in Nodinite 7.x. Retention policies are configurable per environment. See Audit Reports and Retention for retention settings.
Entity Audit Metadata
Every Repository Model entity (Integration, System, Service, Resource) tracks these audit metadata fields:
| Field Name | Data Type | Description | Example Value |
|---|---|---|---|
CreatedBy |
String (email/username) | User who created the entity | alice.johnson@contoso.com |
CreatedDate |
DateTime (UTC) | When entity was created | 2025-12-15T09:30:00Z |
LastModifiedBy |
String (email/username) | User who last modified the entity | bob.taylor@contoso.com |
LastModifiedDate |
DateTime (UTC) | Timestamp of most recent modification | 2026-01-19T14:22:35Z |
RowVersion |
Byte[] (concurrency token) | Auto-incremented version for optimistic locking | AAAAAAAAB9E= (Base64) |
ModificationCount |
Integer | Total number of modifications | 42 |
Audit Metadata in Entity Detail Panel
<div class="entity-audit-metadata" aria-label="Entity audit information">
<h3>
<i class="fas fa-clock-rotate-left" aria-hidden="true"></i>
Audit Information
</h3>
<dl class="metadata-list">
<dt>Created By:</dt>
<dd>
<a href="mailto:alice.johnson@contoso.com">Alice Johnson</a>
on <time datetime="2025-12-15T09:30:00Z">Dec 15, 2025 at 9:30 AM</time>
</dd>
<dt>Last Modified By:</dt>
<dd>
<a href="mailto:bob.taylor@contoso.com">Bob Taylor</a>
on <time datetime="2026-01-19T14:22:35Z">Jan 19, 2026 at 2:22 PM</time>
<span class="modification-count" title="Total modifications">(42 edits)</span>
</dd>
<dt>Actions:</dt>
<dd>
<button onclick="showChangeHistory()" class="btn-link"
aria-label="View full change history">
<i class="fas fa-list" aria-hidden="true"></i>
View Change History
</button>
</dd>
</dl>
</div>
.entity-audit-metadata {
background-color: #f8f9fa;
border-left: 3px solid #0056b3;
padding: 16px;
margin-top: 24px;
border-radius: 4px;
}
.metadata-list {
display: grid;
grid-template-columns: auto 1fr;
gap: 8px 16px;
font-size: 14px;
}
.metadata-list dt { font-weight: 600; color: #495057; }
.metadata-list dd { color: #212529; margin: 0; }
.modification-count { color: #6c757d; font-size: 13px; }
Change History Log Structure
Field-level change history is stored in the EntityChangeLog table:
Database Schema (SQL Server)
CREATE TABLE [dbo].[EntityChangeLog]
(
[ChangeId] UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
[EntityType] NVARCHAR(50) NOT NULL, -- 'Integration','System','Service','Resource'
[EntityId] UNIQUEIDENTIFIER NOT NULL,
[EntityName] NVARCHAR(255) NULL, -- Denormalized for reporting performance
[ChangeType] NVARCHAR(20) NOT NULL, -- 'CREATE','UPDATE','DELETE'
[FieldName] NVARCHAR(100) NULL, -- NULL for CREATE/DELETE; specific field for UPDATE
[OldValue] NVARCHAR(MAX) NULL, -- Previous value (NULL for CREATE)
[NewValue] NVARCHAR(MAX) NULL, -- New value (NULL for DELETE)
[ChangedBy] NVARCHAR(255) NOT NULL, -- Email or username
[ChangedDate] DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
[ChangeReason] NVARCHAR(500) NULL, -- Optional commit message
[SessionId] NVARCHAR(100) NULL, -- Groups related changes from same save
[IPAddress] NVARCHAR(45) NULL, -- IPv4/IPv6 for security audits
[UserAgent] NVARCHAR(500) NULL, -- Browser/client information
INDEX [IX_EntityChangeLog_EntityId] ([EntityId], [ChangedDate] DESC),
INDEX [IX_EntityChangeLog_ChangedBy] ([ChangedBy], [ChangedDate] DESC),
INDEX [IX_EntityChangeLog_ChangedDate]([ChangedDate] DESC),
INDEX [IX_EntityChangeLog_EntityType] ([EntityType], [ChangedDate] DESC)
);
API Response (JSON)
{
"changeId": "550e8400-e29b-41d4-a716-446655440000",
"entityType": "Integration",
"entityId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entityName": "SAP to Salesforce Sync",
"changeType": "UPDATE",
"fieldName": "Description",
"oldValue": "Legacy description from 2024",
"newValue": "Updated description with GDPR compliance notes",
"changedBy": "alice.johnson@contoso.com",
"changedDate": "2026-01-19T14:22:35.123Z",
"changeReason": "Added GDPR compliance documentation per legal review",
"sessionId": "session_abc123",
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0"
}
Change History Timeline UI
<div class="change-history-panel" role="dialog" aria-labelledby="change-history-title">
<h2 id="change-history-title">
<i class="fas fa-clock-rotate-left" aria-hidden="true"></i>
Change History: Integration #123
</h2>
<div class="history-filters">
<label for="user-filter">Filter by User:</label>
<select id="user-filter" aria-label="Filter changes by user">
<option value="">All Users</option>
<option value="alice.johnson@contoso.com">Alice Johnson</option>
<option value="bob.taylor@contoso.com">Bob Taylor</option>
</select>
<label for="date-filter">Date Range:</label>
<select id="date-filter" aria-label="Filter changes by date range">
<option value="7d" selected>Last 7 days</option>
<option value="30d">Last 30 days</option>
<option value="90d">Last 90 days</option>
</select>
</div>
<div class="change-timeline" role="list" aria-label="Change history timeline">
<!-- Change entry -->
<div class="change-entry" role="listitem">
<img src="avatar-alice.jpg" alt="Alice Johnson"
class="change-avatar" style="z-index: 1;">
<div class="change-content">
<div class="change-header">
<strong>Alice Johnson</strong>
<span class="change-type change-type-update">UPDATE</span>
<time datetime="2026-01-19T14:22:35Z">Jan 19, 2026 at 2:22 PM</time>
</div>
<div class="change-detail">
<strong>Description</strong> changed:
<span class="diff-old">Legacy description from 2024</span>
→
<span class="diff-new">Updated description with GDPR notes</span>
</div>
<div class="change-reason">
<i class="fas fa-comment" aria-hidden="true"></i>
<em>Added GDPR compliance documentation per legal review</em>
</div>
<button class="btn-revert" onclick="revertChange('550e8400...')"
aria-label="Revert this change by Alice Johnson">
<i class="fas fa-rotate-left" aria-hidden="true"></i> Revert
</button>
</div>
</div>
</div>
</div>
.change-timeline { position: relative; padding-left: 48px; }
.change-timeline::before {
content: '';
position: absolute;
left: 16px; top: 0; bottom: 0;
width: 2px;
background-color: #e0e0e0;
}
.change-entry { display: flex; gap: 16px; margin-bottom: 24px; }
.change-avatar { width: 40px; height: 40px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 2px 4px rgba(0,0,0,.2); }
.change-type { padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; }
.change-type-update { background: #fff3e0; color: #e65100; }
.change-type-create { background: #e8f5e9; color: #1b5e20; }
.change-type-delete { background: #ffebee; color: #b71c1c; }
.diff-old { background-color: #ffebee; padding: 2px 4px; border-radius: 2px; text-decoration: line-through; color: #b71c1c; }
.diff-new { background-color: #e8f5e9; padding: 2px 4px; border-radius: 2px; color: #1b5e20; }
.change-reason { border-left: 3px solid #0056b3; padding-left: 8px; color: #6c757d; font-size: 13px; margin: 8px 0; }
Filter Examples: Recent Modifications
| Filter Description | Query Syntax | Use Case |
|---|---|---|
| All changes in last 7 days | modified:7d |
Weekly review |
| Changes by specific user | lastModifiedBy:alice@contoso.com |
Track individual contributions |
| Changes since specific date | modified:>2026-01-15 |
Compliance audit for period |
| Frequently modified entities | modificationCount:>10 |
Identify high-churn integrations |
| Entities created in last 30 days | created:30d |
Track new integrations |
| Entities not modified in 90 days | modified:>90d |
Find stale/abandoned integrations |
| Combined: Alice's changes this week | lastModifiedBy:alice@contoso.com AND modified:7d |
Targeted team review |
| Others' changes since my last login | lastModifiedBy:NOT {currentUser} |
Morning catch-up |
Filter UI
<div class="recent-changes-filter" role="search" aria-label="Filter by recent modifications">
<h3><i class="fas fa-filter" aria-hidden="true"></i> Filter by Recent Changes</h3>
<form id="change-filter-form">
<div class="form-row">
<label for="date-range">Modified In:</label>
<select id="date-range" name="dateRange">
<option value="1d">Last 24 hours</option>
<option value="7d" selected>Last 7 days</option>
<option value="30d">Last 30 days</option>
<option value="90d">Last 90 days</option>
<option value="custom">Custom date range...</option>
</select>
</div>
<div class="form-row">
<label for="modified-by">Modified By:</label>
<select id="modified-by" name="modifiedBy" multiple aria-label="Select users">
<option value="">All users</option>
<option value="alice.johnson@contoso.com">Alice Johnson</option>
<option value="bob.taylor@contoso.com">Bob Taylor</option>
</select>
</div>
<div class="form-row">
<label for="modification-count">Modification Count:</label>
<select id="modification-count" name="modificationCount">
<option value="">Any</option>
<option value=">5">More than 5 edits</option>
<option value=">10">More than 10 edits</option>
<option value=">20">More than 20 edits</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">
<i class="fas fa-search" aria-hidden="true"></i> Apply Filter
</button>
<button type="reset" class="btn-secondary">Clear Filters</button>
</div>
</form>
<div class="filter-results" role="status" aria-live="polite">
<p><strong>42 entities</strong> modified in last 7 days</p>
</div>
</div>
Related Topics
- Multi-User Collaboration Hub — full feature overview
- Architecture and Presence — real-time system design
- Scalability and Offline Editing — performance and offline support
- Audit Reports and Retention — compliance reports, GDPR deletion, data retention
- Comments and Annotations — team collaboration on entities
- Comment Status and UI — approval workflows