Skip to main content

Compatibility Identity Storage

Summary

Source-backed behavior of CompatId, the numeric compatibility identity carried on the Asset aggregate. It is a property on the aggregate — not a separate table — that preserves the monolith asset-record identity space so the frontend and monolith-shaped compatibility surface can address assets by their legacy numeric id.

Audience

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

Overview

CompatId is an integer property mapped onto the Assets table row, alongside the aggregate's Guid primary key. It exists so migrated assets keep the same numeric identifier they had in the monolith, allowing the compatibility APIs and existing frontend to resolve assets without a Guid. There is no dedicated compatibility table and no separate identity entity; the value lives on the aggregate itself.

Confirmed persistence behavior

  • Property, not a table: CompatId is an integer property on the Asset aggregate root, persisted as a column on the Assets table. There are zero separate compatibility tables.
  • Runtime generation: at service runtime the column is a database identity column (UseIdentityByDefaultColumn), governed by the CompatIdStoreGenerated => true flag on AssetDbContext. New assets created through the running service receive a database-generated value.
  • Backfill generation: the backfill DbContext subclass overrides CompatIdStoreGenerated to false, mapping the column as ValueGeneratedNever. This lets the monolith asset-record identifier be inserted verbatim as the CompatId, so migrated rows keep their original numeric id rather than receiving a fresh identity value.
  • Uniqueness: a unique index UX_Assets_CompatId enforces that CompatId values do not collide within the table.
  • Lookup: the repository exposes GetByCompatIdAsync, which loads an asset (including history and document references) by its CompatId. This is the resolution path used by the monolith-shaped compatibility surface.
  • Tenant scope: CompatId rows are subject to the same global query filter as the rest of the Asset aggregate (IsSuperAdmin || TenantId == CurrentTenantId), so lookups are tenant-scoped through the aggregate filter. See Tenant Isolation.
  • Collision handling: the only collision guard is the UX_Assets_CompatId unique index. No cross-tenant global de-duplication or reservation strategy is documented in source.

Classification

Implemented compatibility-identity property with a Transitional purpose (monolith parity during migration).

Requires confirmation

  • The long-term retirement strategy for CompatId — whether and when the compatibility identity is decommissioned once the monolith surface is retired — is transitional and requires confirmation.
  • Whether CompatId uniqueness should be scoped per tenant rather than table-global is not decided in source and requires confirmation.

Diagram

See Also

Keywords

  • Asset compatibility
  • Compatibility Identity Storage
  • Compatibility identity

Source References

  • microservices/src/asset-service/Domain/Asset/Asset.cs
  • microservices/src/asset-service/Infrastructure/AssetDbContext.cs
  • microservices/src/asset-service/Backfill/AssetRecordBackfill.cs
  • microservices/src/asset-service/Domain/Repositories.cs

Revision Information

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