Config Platform - Domain Model Schema¶
Overview¶
This document provides structured schemas for Config Platform domain models. Use these schemas to generate domain entities, aggregate roots, value objects, and persistence mappings.
Aggregate Roots¶
ConfigItem Aggregate¶
Schema:
ConfigItem:
type: aggregate_root
properties:
id:
type: uuid
required: true
description: Unique identifier
key:
type: string
required: true
maxLength: 500
pattern: "^[a-zA-Z0-9._-]+$"
description: Configuration key (dot-notation supported)
value:
type: any
required: true
description: Configuration value (JSON, string, number, boolean)
contentType:
type: string
enum: [application/json, text/plain, application/yaml, text/xml]
default: application/json
isSecret:
type: boolean
default: false
description: Indicates if value contains sensitive data
isFeatureToggle:
type: boolean
default: false
description: Indicates if this is a feature flag
labels:
type: array
items:
type: string
description: Tags for categorization and filtering
description:
type: string
maxLength: 1000
version:
type: integer
required: true
description: Current version number
etag:
type: string
required: true
description: Entity tag for optimistic concurrency
createdAt:
type: datetime
required: true
updatedAt:
type: datetime
required: true
createdBy:
type: string
required: true
updatedBy:
type: string
required: true
invariants:
- key must be unique within config set and tenant
- value must pass schema validation if schema is defined
- version increments on each update
- etag changes on each update
relationships:
belongsTo:
- ConfigSet
hasMany:
- ConfigVersion
C# Domain Model:
public class ConfigItem : AggregateRoot<Guid>
{
public string Key { get; private set; }
public object Value { get; private set; }
public string ContentType { get; private set; }
public bool IsSecret { get; private set; }
public bool IsFeatureToggle { get; private set; }
public List<string> Labels { get; private set; }
public string Description { get; private set; }
public int Version { get; private set; }
public string ETag { get; private set; }
public DateTime CreatedAt { get; private set; }
public DateTime UpdatedAt { get; private set; }
public string CreatedBy { get; private set; }
public string UpdatedBy { get; private set; }
public Guid ConfigSetId { get; private set; }
public ConfigSet ConfigSet { get; private set; }
public ICollection<ConfigVersion> Versions { get; private set; }
public void UpdateValue(object newValue, string updatedBy)
{
// Business logic: validate, increment version, update etag
}
}
ConfigVersion Entity¶
Schema:
ConfigVersion:
type: entity
properties:
id:
type: uuid
required: true
configItemId:
type: uuid
required: true
foreignKey: ConfigItem.id
versionNumber:
type: integer
required: true
description: Immutable version number
value:
type: any
required: true
description: Snapshot of value at this version
changeSummary:
type: string
maxLength: 500
description: Human-readable description of change
createdBy:
type: string
required: true
createdAt:
type: datetime
required: true
hash:
type: string
required: true
description: SHA-256 hash of value for integrity
invariants:
- versions are immutable (append-only)
- version numbers are sequential
- hash must match value content
relationships:
belongsTo:
- ConfigItem
ConfigBundle Aggregate¶
Schema:
ConfigBundle:
type: aggregate_root
properties:
id:
type: uuid
required: true
name:
type: string
required: true
maxLength: 200
appId:
type: string
required: true
description: Application identifier
environment:
type: string
enum: [dev, staging, prod]
required: true
scope:
type: string
enum: [global, edition, tenant, service, instance]
required: true
description: Configuration scope level
tenantId:
type: uuid
description: Tenant identifier (required if scope is tenant or service)
editionId:
type: string
description: Edition identifier (required if scope is edition)
serviceId:
type: string
description: Service identifier (required if scope is service or instance)
labels:
type: array
items:
type: string
status:
type: string
enum: [draft, published, archived]
default: draft
version:
type: integer
required: true
etag:
type: string
required: true
createdAt:
type: datetime
required: true
updatedAt:
type: datetime
required: true
invariants:
- name must be unique within tenant and environment
- scope determines required identifiers
- status transitions: draft -> published -> archived
relationships:
hasMany:
- ConfigItem
- ConfigSnapshot
ConfigSchema Value Object¶
Schema:
ConfigSchema:
type: value_object
properties:
id:
type: uuid
required: true
name:
type: string
required: true
maxLength: 200
jsonSchema:
type: object
required: true
description: JSON Schema definition for validation
version:
type: string
required: true
description: Schema version (semantic versioning)
appliesTo:
type: array
items:
type: string
description: Config keys this schema applies to (supports wildcards)
createdAt:
type: datetime
required: true
updatedAt:
type: datetime
required: true
invariants:
- jsonSchema must be valid JSON Schema
- version follows semantic versioning
relationships:
validates:
- ConfigItem
JSON Schema Example:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"apiUrl": {
"type": "string",
"format": "uri",
"description": "API base URL"
},
"timeout": {
"type": "integer",
"minimum": 1,
"maximum": 300,
"description": "Request timeout in seconds"
},
"retryCount": {
"type": "integer",
"minimum": 0,
"maximum": 10
}
},
"required": ["apiUrl", "timeout"]
}
TenantConfig Aggregate¶
Schema:
TenantConfig:
type: aggregate_root
properties:
id:
type: uuid
required: true
tenantId:
type: uuid
required: true
unique: true
editionId:
type: string
required: true
description: Product edition (Free, Pro, Enterprise)
configSet:
type: object
description: Resolved configuration set
overrides:
type: object
description: Tenant-specific overrides
version:
type: integer
required: true
createdAt:
type: datetime
required: true
updatedAt:
type: datetime
required: true
invariants:
- tenantId must be unique
- overrides must pass edition policy validation
relationships:
hasMany:
- ServiceConfig
belongsTo:
- EditionConfig
ServiceConfig Entity¶
Schema:
ServiceConfig:
type: entity
properties:
id:
type: uuid
required: true
tenantConfigId:
type: uuid
required: true
foreignKey: TenantConfig.id
serviceId:
type: string
required: true
description: Microservice identifier
configItems:
type: array
items:
$ref: ConfigItem
version:
type: integer
required: true
createdAt:
type: datetime
required: true
updatedAt:
type: datetime
required: true
relationships:
belongsTo:
- TenantConfig
hasMany:
- ConfigItem
Entity Relationship Diagram¶
erDiagram
ConfigBundle ||--o{ ConfigItem : contains
ConfigItem ||--o{ ConfigVersion : versions
ConfigItem }o--|| ConfigSchema : validates
TenantConfig ||--o{ ServiceConfig : contains
TenantConfig }o--|| EditionConfig : inherits
ServiceConfig ||--o{ ConfigItem : holds
ConfigBundle ||--o{ ConfigSnapshot : snapshots
Hold "Alt" / "Option" to enable pan & zoom
Validation Rules¶
ConfigItem Validation¶
validation_rules:
key:
- required: true
- pattern: "^[a-zA-Z0-9._-]+$"
- maxLength: 500
- uniqueWithin: [configSetId, tenantId]
value:
- required: true
- validateAgainstSchema: true
- secretDetection: true
contentType:
- enum: [application/json, text/plain, application/yaml, text/xml]
labels:
- maxItems: 20
- uniqueItems: true
ConfigBundle Validation¶
validation_rules:
name:
- required: true
- maxLength: 200
- uniqueWithin: [tenantId, environment]
scope:
- required: true
- conditionalRequired:
- if: scope == "tenant" or "service"
then: tenantId required
- if: scope == "edition"
then: editionId required
- if: scope == "service" or "instance"
then: serviceId required
Persistence Mapping¶
NHibernate Mapping Example¶
<hibernate-mapping>
<class name="ConfigItem" table="config_items">
<id name="Id" column="id" type="guid">
<generator class="guid.comb"/>
</id>
<property name="Key" column="key" type="string" length="500" not-null="true"/>
<property name="Value" column="value" type="string" length="10000" not-null="true"/>
<property name="ContentType" column="content_type" type="string" length="100"/>
<property name="IsSecret" column="is_secret" type="boolean"/>
<property name="IsFeatureToggle" column="is_feature_toggle" type="boolean"/>
<property name="Labels" column="labels" type="string" length="1000"/>
<property name="Description" column="description" type="string" length="1000"/>
<property name="Version" column="version" type="int" not-null="true"/>
<property name="ETag" column="etag" type="string" length="64" not-null="true"/>
<property name="CreatedAt" column="created_at" type="datetime" not-null="true"/>
<property name="UpdatedAt" column="updated_at" type="datetime" not-null="true"/>
<property name="CreatedBy" column="created_by" type="string" length="200" not-null="true"/>
<property name="UpdatedBy" column="updated_by" type="string" length="200" not-null="true"/>
<many-to-one name="ConfigSet" column="config_set_id" class="ConfigBundle" not-null="true"/>
<bag name="Versions" cascade="all-delete-orphan">
<key column="config_item_id"/>
<one-to-many class="ConfigVersion"/>
</bag>
</class>
</hibernate-mapping>
Domain Events¶
ConfigItem Events¶
public class ConfigItemCreatedEvent : IDomainEvent
{
public Guid ConfigItemId { get; set; }
public string Key { get; set; }
public Guid ConfigSetId { get; set; }
public string TenantId { get; set; }
public DateTime OccurredAt { get; set; }
}
public class ConfigItemUpdatedEvent : IDomainEvent
{
public Guid ConfigItemId { get; set; }
public string Key { get; set; }
public int OldVersion { get; set; }
public int NewVersion { get; set; }
public DateTime OccurredAt { get; set; }
}
public class ConfigItemDeletedEvent : IDomainEvent
{
public Guid ConfigItemId { get; set; }
public string Key { get; set; }
public DateTime OccurredAt { get; set; }
}
References¶
- Solution Architecture - Domain model design details
- API Contract Specification - API data structures
- 00 Overview - Domain model overview