Storage¶
Target Architecture — Final-State Design
This page describes the final-state storage topology of the Marketplace Platform. Relational state uses Azure SQL / PostgreSQL via NHibernate; asset package bytes use Azure Blob Storage (asset packages), Azure Artifacts (NuGet/distributable feeds), and the Azure Container Registry (container images); read paths use Redis and a search index.
The Marketplace separates metadata (relational, queryable, tenant-scoped) from artifacts (large, immutable binary packages in object/artifact stores). Each store has a single owning context to preserve the bounded-context isolation described in Data Model.
Storage map¶
| Data | Store | Owner Service | Access Pattern | Retention | Notes |
|---|---|---|---|---|---|
| Catalog metadata (assets, media, tags) | Azure SQL / PostgreSQL | MarketplaceCatalogService | Read-heavy; faceted reads via cache/index | Life of asset (+soft-delete) | Source of truth for catalog; projected to search index |
| Search documents | Search index (Azure AI Search / Elasticsearch) | MarketplaceSearchService | Query-heavy; full-text + facets | Rebuildable from catalog | Derived read model; reindexed by AssetIndexingWorker |
| Asset version metadata | Azure SQL / PostgreSQL | AssetVersionService | Write-once on release; read on install | Life of asset (+grace) | Immutable after release |
| Asset packages (Zip bundles) | Azure Blob Storage | AssetVersionService / AssetPublishingService | Write-once; read on install; staging on submit | While referenced (+12-month grace) | Immutable, content-hash addressed; staging container for submissions |
| Distributable packages (NuGet) | Azure Artifacts | AssetVersionService | Restore on install/build | While referenced | Library Packs / Template Packs feed |
| Container images | Azure Container Registry (ACR) | AssetVersionService | Pull on install/deploy | While referenced | For asset types shipping images |
| Compatibility metadata & verdicts | Azure SQL / PostgreSQL + Redis | AssetCompatibilityService | Read-heavy; cached verdicts | 90 days persisted; cache TTL | Version-keyed cache invalidation |
| Dependency graphs | Azure SQL / PostgreSQL + Redis | DependencyResolutionService | Compute + cache | Cache TTL; recompute on miss | Graph cache keyed by (assetId, version, targetHash) |
| Installations & saga state | Azure SQL / PostgreSQL | AssetInstallationService | Transactional; provenance reads | Project life + 24 months | Saga state co-located with aggregate |
| Licenses & entitlements | Azure SQL / PostgreSQL | LicenseService | Transactional; sync entitlement check | Entitlement life + billing retention | Federated with ConnectSoft.Extensions.Saas.Billing |
| Pricing plans | Azure SQL / PostgreSQL | PricingService | Read on quote; write on publish | Life of plan | Metering via ConnectSoft.Extensions.Saas.Metering |
| Publishers & signing-key refs | Azure SQL / PostgreSQL | PublisherPortalService | Read on publish; admin writes | Life of publisher | Signing keys referenced in Azure Key Vault, never stored in SQL |
| Reviews & ratings | Azure SQL / PostgreSQL | ReviewRatingService | Write on review; read for aggregates | Life of asset (+soft-delete) | Aggregate rating projected to catalog |
| Cache (catalog reads, sessions) | Redis | Catalog, Search, Compatibility, Dependency | Hot-path reads | TTL | Version-keyed invalidation on release/review |
Relational stores (Azure SQL / PostgreSQL)¶
All transactional domain state is relational, mapped through NHibernate per the Clean Architecture PersistenceModel.NHibernate layer. Azure SQL is the default; PostgreSQL is supported for tenants or deployments standardizing on it (the ConnectSoft.Extensions.PersistenceModel.PostgreSQL flavor). Each bounded context owns its database/schema; schema migrations ship via the DatabaseModel.Migrations project.
Object and package stores¶
- Azure Blob Storage holds asset package bundles (Zip): a
stagingcontainer for in-flight submissions and an immutable, content-hash-addressedreleasedcontainer for published packages. Blobs are write-once; theContentHashonAssetPackageguards integrity. - Azure Artifacts hosts distributable NuGet feeds for Library Packs and Template Packs, so installation and downstream builds restore them like any other dependency.
- Azure Container Registry (ACR) hosts container images for asset types that distribute runnable images. Images are referenced by digest for immutability.
Selection of store follows AssetPackage.PackageType: Zip → Blob, NuGet → Artifacts, ContainerImage → ACR.
Caching and search¶
- Redis caches catalog detail, compatibility verdicts, and resolved dependency graphs on the read hot path; entries are invalidated by version-keyed events (
AssetVersionReleased,AssetReviewed). - The search index is a derived read model rebuilt by
AssetIndexingWorkerfrom catalog, version, and review events; it can be fully reconstructed from the relational source of truth at any time.
Backup, integrity, and isolation¶
- Relational stores use Azure-managed automated backups and point-in-time restore; package stores rely on immutability plus geo-redundant replication.
- Package integrity is enforced by
ContentHashverification on read and by publisher signing (see Security). - Tenant isolation is enforced at the data layer (row-level
TenantIdfilters) and at the storage layer (per-tenant blob path prefixes / containers where required), consistent with Data Model.
Continue to Data Model, Security, and Deployment.