Skip to main content

Assignment History Storage

Summary

Source-backed persistence of the AssetAssignmentHistory child entity — the append-only log of lifecycle and assignment actions taken against an asset, including its key strategy, columns, indexes, and immutability guarantees.

Audience

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

Overview

AssetAssignmentHistory is an aggregate child owned by the Asset aggregate root. Each row records a single action performed against one asset (creation, request, approval, issue, return, rejection, damage, loss, retirement, mark-available, or update) together with the actor and the condition observed at that moment. The rows map to the AssetAssignmentHistory table and cascade from the parent Assets row. History rows are the historical audit trail of assignment activity; they are distinct from the asset's current assignment state, which lives on the Asset aggregate itself.

Confirmed persistence behavior

FieldStorageRequiredNotes
IdGuid primary key (ValueGeneratedNever)YesApp-assigned so a navigation-added row is treated as an INSERT rather than a phantom-Modified update
TenantIdintegerYesTenant scope; participates in query filter and composite index
AssetIdGuid foreign keyYesReferences the parent Assets row (cascade delete)
Actionvarchar(60)YesFree-text action label (Created, Requested, Approved, Issued, Returned, Rejected, Damaged, Lost, Retired, Available, Updated)
UserIdintegerNoIdentifier-only reference; no foreign key
LaborIdintegerNoIdentifier-only reference; no foreign key
ConditionAssetCondition enum → varchar(40)YesStored as string, not integer
Notesvarchar(2000)NoFree text
Actorvarchar(256)YesDefaults to system when no actor context is present
OccurredOnUtctimestamptzYesWhen the action occurred
  • Parent ownership: rows are added only through the aggregate (AddHistory); the child is configured HasMany history WithOne with HasForeignKey(AssetId) and OnDelete(Cascade).
  • Cardinality: one Asset has zero-or-many history rows (1..*). Deleting an asset cascades and removes its history rows.
  • Explicit key generation: the Guid primary key is ValueGeneratedNever, so the application supplies the value and EF inserts nav-added rows rather than mis-tracking them as modifications.
  • Enum as string: Condition persists as a string via the AssetCondition conversion.
  • Append-only immutability: history rows are inserted and never mutated in place. There is no update or soft-delete path for an existing history row.
  • Ordering: history is ordered by OccurredOnUtc in application code (for example the detail and history queries); there is no dedicated ordering index beyond the indexes listed below.
  • Tenant filter: yes — the global query filter (IsSuperAdmin || TenantId == CurrentTenantId) applies to this entity.

Current state versus history

The asset's current assignment state (Assignee, AssignedOnUtc, Status) is held on the Asset aggregate and is overwritten on each transition. The history rows are the immutable record of what happened over time. See Asset Storage.

Indexes

  • IX_AssetAssignmentHistory_AssetId — convention-generated single-column index on the foreign key.
  • IX_AssetHistory_Tenant_Asset — composite index on (TenantId, AssetId).

Missing constraints

  • There is no one-active-assignment constraint at the database level. Nothing prevents multiple rows implying overlapping assignments; assignment correctness is governed by the aggregate's lifecycle state, not by a database rule.
  • UserId and LaborId are identifier-only values with no foreign keys.

Classification

Implemented append-only aggregate-child persistence.

Requires confirmation

Whether an active-assignment constraint or history-retention policy is required is not decided in source and requires confirmation.

Diagram

See Also

Keywords

  • Assignment history
  • Assignment History Storage
  • Draft database documentation

Source References

  • microservices/src/asset-service/Domain/Asset/Asset.cs
  • microservices/src/asset-service/Infrastructure/AssetDbContext.cs
  • microservices/src/asset-service/Application/Queries/AssetQueries.cs
  • microservices/src/asset-service/Infrastructure/Migrations/AssetDbContextModelSnapshot.cs

Revision Information

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