Skip to content
bitzorcas
中EN

Concept

Master Data and Reference Catalogs

Source-verified handbook for nine tenant catalogs, eight CSV seed steps, dictionary resolution, caching, host composition, and current product boundaries.

Last updated

Master Data is not currently an MDM suite with approvals, versions, quality rules, and an administration UI. It physically owns nine tenant-scoped catalog records, eight CSV seed steps, the shared IDataDictionaryResolver implementation, and a read-only governance query endpoint. Infrastructure is still the data owner, but Contracts and Application projects now exist to expose the governance report.

1. Current product surface

8 embedded CSVs

8 EntitySet seed steps

9 CatalogRecord tables

MasterDataDictionaryResolver

application display projection

compile-time Bitz metadata

API/JobHost composition

SysTranslationCatalogRecord is the ninth table but has no MasterData CSV/step; I18n provides its translation workflows.

Alongside Infrastructure, Contracts and Application projects now exist to expose the read-only governance report (see §12).

2. Physical structure

src/Platform/MasterData/
└── BitzOrcas.Platform.MasterData.Infrastructure/
├── Persistence/ # 9 CatalogRecords
├── Seeders/ # 8 ORM-neutral seed steps
│ └── Assets/ # 8 caret-delimited CSVs
├── Dictionary/
├── MasterDataDependencyInjection.cs
├── MasterDataFeatures.cs
├── MasterDataPermissions.cs
└── MasterDataModule.cs

The project references Application, Infrastructure, Persistence.Models, and the compile-time metadata generator, but no SqlSugar or EF Core adapter assembly.

3. Nine catalogs

RecordTableCurrent purpose
SysLanguageCatalogRecordSysLanguagetenant language catalog read by I18n
SysCountryCatalogRecordSysCountryISO country/region fields
SysIndustrySettingCatalogRecordSysIndustrySettingindustry tree
SysGeneralCodeGroupCatalogRecordSysGeneralCodeGroupdictionary group hierarchy
SysGeneralCodeCatalogRecordSysGeneralCodecode, group, hierarchy, display
SysGeneralCodeTextCatalogRecordSysGeneralCodeTextlocalized dictionary display
SysExchangeRateCatalogRecordSysExchangeRatedated currency-pair snapshot
SysPublicHolidayCatalogRecordSysPublicHolidaycountry/year holiday
SysTranslationCatalogRecordSysTranslationI18n scoped translation

All inherit BizEntityBase and declare tenant and soft-delete metadata.

4. Ownership transfer

Older code placed these rows and SqlSugar-specific seeders in Framework. Architecture gates keep those paths deleted and require owner-local models. This removes business reference data from Framework and runs the same step through IEntitySet<T> on supported ORMs.

MasterData is an explicit multi-table reference-catalog exception to the unified aggregate rule. These records are not an invitation to restore one-to-one *Entity + mapper files.

5. Host composition

The API references this project and currently composes it as follows:

Current composition
// ① Generated ORM adapters provide all nine IEntitySet<T> services.
services.AddBitzOrcasGeneratedPersistenceAdapters(persistenceProvider);
// ② MasterData registers only the dictionary resolver.
services.AddBitzOrcasMasterDataPlatform();
// ③ Seed framework and generated manifest discover the eight steps.
services.AddBitzOrcasSeeders(configuration);
services.AddBitzOrcasGeneratedSeedSteps();

JobHost also references the project. A reference does not prove seed execution; orchestration configuration and host lifecycle still decide that.

6. Real dictionary API

MethodBehavior
ResolveAsync(group, code, culture)display name or original code
ResolveListAsync(group, csvCodes, culture)ordered comma-list resolution
ResolveBatchAsync(requests, culture)grouped request-to-text map
ListEntriesAsync(group, culture)active non-deleted entries by Sort
InvalidateCacheAsync(group?)removes the whole dictionary tag

The previous page’s ReferenceKey, nullable ReferenceValue, and stable-key overload do not exist.

7. Correct consumption

Persist code, resolve at read time
// ① Business rows persist the stable code, never mutable display text.
order.PaymentMethodCode = request.PaymentMethodCode;
await orders.UpdateAsync(order, cancellationToken);
// ② Use the actual groupKey + code + culture signature.
var displayName = await dictionaries.ResolveAsync(
groupKey: "PAYMENTMETHODCODE",
code: order.PaymentMethodCode,
culture: currentCulture.Name,
cancellationToken);
// ③ A miss returns the original code, so expose both machine and display forms.
return new PaymentMethodDto(order.PaymentMethodCode, displayName);

The contract cannot distinguish a missing translation from a display value equal to the code, and returns no effective culture.

8. Seed asset reality

AssetCurrent data rows
language2
country0 (header only)
industry0 (header only)
general-code-group177
general-code43,603
general-code-text0 (header only)
exchange-rate0 (header only)
public-holiday347

Owning a seed step does not mean the product ships data for every catalog. See seeding and assets.

9. Guarantees and non-guarantees

Current guaranteeDo not assume
compile-time metadata for nine recordsmaster-data management API/UI
ORM-neutral seed stepsstrict CSV schema validation
tenant-scoped dictionary cache keysgroup invalidation is tenant-local
case-insensitive code mapnormalized culture fallback chain
missing code returns original valuecaller can detect the miss reason
API host registers the resolverfeature/permission endpoint enforcement

10. Confirmed risks

  1. Localized seed matching and lookup use Code+Language but omit Class/Group.
  2. Localized maps use Code as a dictionary key; duplicates can throw.
  3. Any group invalidation removes the entire dictionary tag.
  4. ListEntriesAsync bypasses the 30-minute group cache.
  5. CSV header/missing-field validation is disabled; key defects only warn.
  6. Exchange-rate CSV says UpdateDate; the model/where key retains ModifyTimee.
  7. Four assets contain only a header, yet a seed run can succeed with zero rows.
  8. 43,603 codes are queried/written one row at a time and need cold-start testing.

11. Handbook map

12. Governance query endpoint

GET /api/master-data/governance (resource master-data/catalog, Action Read) is an owner-local read-only governance report that lets operators see the scale of each reference catalog and the dictionary contents. Query parameters: GroupCode (optional, selects a dictionary group), Culture (optional, BCP-47), Search (optional), EntryLimit (default 100, max 200).

Returns MasterDataGovernanceReport:

  • Catalogs: count summaries for nine catalogs (languages, countries, industries, dictionaryGroups, dictionaryEntries, dictionaryTexts, exchangeRates, publicHolidays, translations), each with Total/Active/SeedManaged;
  • DictionaryGroups and Entries: when a GroupCode is selected, returns paged dictionary entries for that group, including localized DisplayName;
  • SelectedGroup, SelectedGroupTotal, Culture, EntryLimit, GeneratedAt.

The read store MasterDataGovernanceReadStore implements IMasterDataGovernanceReadStore via IEntitySet<T> projections; it degrades to the fail-closed UnavailableMasterDataGovernanceReadStore when not registered. Error codes: MasterData.Governance.StoreUnavailable (ServiceUnavailable), MasterData.Governance.InvalidQuery (Validation).

This endpoint is the same kind of read-only projection as the Operations adapter/connector report: it answers how much and what, not whether it is correct or current.

13. Source inspection

Terminal window
# Expect nine records, eight seed steps, and eight assets.
find src/Platform/MasterData -type f | sort
# Verify actual default-host composition.
rg -n "AddBitzOrcasMasterDataPlatform|AddBitzOrcasGeneratedSeedSteps" src/Hosts -g '*.cs'
# Legacy ownership paths should remain absent.
find src/Framework src/Platform/MasterData -path '*MasterData*Entity.cs' -o -path '*SqlSugar*MasterData*'

Back to platform modules · I18n module

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%