Skip to main content

Audit and Timeline Storage

Summary

Source-backed persistence of the two asset evidence tables — AssetAuditLogs and AssetTimeline. Both are append-only, tenant-scoped, and staged within the same unit of work as the aggregate change they describe.

Audience

Backend engineers, database reviewers, architects, QA, support, operations, security reviewers, and product owners.

Overview

The Asset Service records two independent evidence streams. AssetAuditLogs captures audit entries — an entity reference, an action, and the acting identity. AssetTimeline captures human-facing timeline entries — an entry type, a category, and a description. They are separate infrastructure entities with separate tables, separate writers, and separate indexes. Neither references the asset with a foreign key; each holds the asset identity as a string.

Confirmed persistence behavior

AssetAuditLogs

FieldStorageRequiredNotes
IdGuid primary keyYes
TenantIdintegerYesTenant scope; participates in query filter and composite index
EntityTypevarchar(120)YesLogical entity descriptor
EntityIdvarchar(80)YesString reference to the asset id — not a foreign key
Actionvarchar(120)YesAudited action label
ActorEmailvarchar(256)YesDefaults to system when no actor context is present
DetailsJsonjsonbNoFree-form detail payload
OccurredAtUtctimestamptzYesOrdering field

Index: IX_AssetAuditLogs_TenantId_OccurredAtUtc on (TenantId, OccurredAtUtc).

AssetTimeline

FieldStorageRequiredNotes
IdGuid primary keyYes
TenantIdintegerYesTenant scope; participates in query filter and composite index
EntityTypevarchar(120)YesLogical entity descriptor
EntityIdvarchar(80)YesString reference to the asset id — not a foreign key
EntryTypevarchar(80)YesTimeline entry classification
Categoryvarchar(60)YesDefaults to Asset
Actorvarchar(256)YesActing identity
Descriptionvarchar(2000)NoFree text
MetadataJsonjsonbNoFree-form metadata payload
OccurredAtUtctimestamptzYesOrdering field

Index: IX_AssetTimeline_Tenant_Occurred on (TenantId, OccurredAtUtc).

  • Actor context: AssetAuditLogs.ActorEmail and AssetTimeline's actor/category fields default to a system value (system / Asset) when no explicit context is supplied.
  • Tenant context: both entities carry TenantId and are covered by the global query filter (IsSuperAdmin || TenantId == CurrentTenantId) — query filter is yes for both.
  • Entity reference by string: EntityType / EntityId describe the referenced asset as strings; there is no foreign key from either table to Assets.
  • Ordering: both tables order by OccurredAtUtc, which is the leading field of each composite index alongside TenantId.
  • Free-form payloads: DetailsJson and MetadataJson are jsonb columns holding free-form content. There are no structured before/after diff columns — the source does not model a field-level change diff.
  • Save-boundary participation: audit rows are staged by an audit writer and timeline rows by a timeline writer, both added within the same unit of work as the aggregate change. They commit together with the aggregate on the single SaveChanges boundary. See Asset Storage.
  • Append-only: both streams are inserted and not mutated; there is no update or soft-delete path for existing evidence rows.
  • No governance in source: there is no redaction, retention, cleanup worker, or access-governance mechanism for either table in source.

Classification

Implemented append-only evidence persistence.

Requires confirmation

Redaction, retention, cleanup, and access-governance for audit and timeline evidence are absent from source and require confirmation.

Diagram

See Also

Keywords

  • Audit timeline
  • Audit and Timeline Storage
  • Draft database documentation

Source References

  • microservices/src/asset-service/Infrastructure/AssetDbContext.cs
  • microservices/src/asset-service/Infrastructure/Persistence.cs
  • microservices/src/asset-service/Application/Commands/AssetCommands.cs
  • microservices/src/asset-service/Infrastructure/Migrations/AssetDbContextModelSnapshot.cs

Revision Information

  • Status: Draft
  • Last reviewed: 2026-07-17
  • Review cycle: Quarterly