Numbering stores rule definitions, segment definitions, and allocation facts separately. String keys connect them; there is no database foreign key or aggregate transaction among the three.
1. Ownership shape
Rules and settings are configuration catalogs. GenerateRecord is runtime fact data and is never seed-managed.
2. Rule index
Rule has a non-unique Tenant + TableName + Field + IsActive + Priority index. The database does not prevent duplicate Table/Field/RuleName, multiple defaults, or duplicate priorities.
The seeder matches TableName + Field + RuleName, but an import natural key is not a unique database constraint.
3. Setting index
Setting indexes RuleId + Sort without uniqueness or explicit TenantId columns. The table still has tenant/soft-delete metadata, but duplicate Sort rows can exist under one rule.
The generator orders by Sort; equal values have undefined order.
4. GenerateRecord indexes
Unique: Tenant + TableName + Field + SequenceNumberStr. Normal: Tenant + TableName + Field + Prefix.
There is no Prefix+SequenceNumber uniqueness, rule version, idempotency request key, or business aggregate Id.
5. Compile-time metadata
// ① The generator collects tenant, soft-delete, and index metadata at compile time.[BitzTable("SysSequenceNumberGenerateRecord", IsTenant = true, IsSoftDelete = true)][BitzIndex( "UX_SysSequenceNumberRecord_Tenant_Table_Field_SeqStr", "TenantId", "TableName", "Field", "SequenceNumberStr", IsUnique = true)]public sealed class SysSequenceNumberGenerateRecord : BizEntityBase{ // ② Full string is the database's final uniqueness guard. [BitzColumn(Length = 128, IsRequired = true)] public string SequenceNumberStr { get; set; } = string.Empty;}Infrastructure consumes only IEntitySet<T> and references no SqlSugar or EF Core adapter.
6. Seed orchestration
| Step | Order | SeedId | Natural key |
|---|---|---|---|
| Rule | 700 | sys_sequence_number_rule | TableName + Field + RuleName |
| Setting | 710 | sys_sequence_number_rule_setting | RuleId + Sort |
Setting explicitly DependsOn Rule. Both use EntitySetCsvSeedStepBase<T> for row-by-row upserts.
7. Current assets
The rule CSV has a header plus two rows; settings has a header plus six. Every row has TenantId=1000001, IsInternal=true, IsEnabled=true, and IsDeleted=false.
RuleIds are DemoCase-SerialId-demo_case_serial and DemoInvoice-SerialId-demo_invoice_serial, matching runtime construction.
8. Seed update boundary
Rule Copy updates separator, compensation, active state, condition, priority, ConditionScope, description, and base tenant/organization/status fields. It does not change TableName, Field, or RuleName.
Setting Copy updates segment configuration and base fields but not RuleId or Sort. A changed natural key inserts a new row; old rows are not desired-state deleted.
9. CSV strictness
The shared reader disables strict HeaderValidated/MissingFieldFound callbacks and mainly warns on suspicious key columns. Numbering adds no rule-DSL lint.
A successful seed does not prove valid condition JSON, type, date format, branch map, unique Sort, or maximum output length.
10. Host composition
The API Host calls AddBitzOrcasNumberingPlatform:
// ① The selected generated ORM adapter provides all three IEntitySet<T> services.services.AddBitzOrcasGeneratedPersistenceAdapters(persistenceProvider);
// ② Numbering registers one scoped implementation of the Framework port.services.AddBitzOrcasNumberingPlatform();
// ③ Generated seed manifests contribute both steps to orchestration.services.AddBitzOrcasGeneratedSeedSteps();There is no Numbering endpoint map.
11. Feature truth
Governance catalogs one default-enabled numbering.sequence Feature. GenerateAsync injects no feature evaluator, and the module has no endpoint or handler applying a gate.
Catalog presence does not prove that tenant plans can disable generation. A calling business use case must enforce it, or a future port decorator must centralize enforcement.
12. No permission or management surface
There is no PermissionCatalog, rule CRUD, publication, preview, version, approval, or audit. Production changes currently require seed/database operations.
A future management API belongs in Numbering Contracts/Application and must not expose IEntitySet to hosts.
13. Business-owner integration
A business module depends on Framework’s ISequenceNumberGenerator, passes stable TableName/Field plus explicit EntityValues, and never references Numbering persistence records.
// ① Include only fields required by conditions and segments.var values = new Dictionary<string, object?>{ ["OfficeId"] = invoice.OfficeId, ["InvoiceType"] = invoice.TypeCode};
// ② The Invoice owner implements the optional callback without exposing IQueryable.var request = new SequenceNumberRequest( "Invoice", "SerialId", values, BusinessSerialContext: invoiceSerialContext);
// ③ Persist the allocated string immediately as aggregate state.var serial = await generator.GenerateAsync(request, cancellationToken);14. Consumption gap
A global source search finds no business Command constructing SequenceNumberRequest. Registration and tests exist, but there is no evidenced production business path. GA needs at least one tracer-bullet consumer.
15. Inspection commands
# Three tables, indexes, and two seed steps.rg -n "BitzTable|BitzIndex|SeedId|WhereColumns|DependsOn" src/Platform/Numbering -g '*.cs'
# Production consumption evidence.rg -n "new SequenceNumberRequest|ISequenceNumberGenerator" src -g '*.cs' --glob '!**/bin/**' --glob '!**/obj/**'