PLATFORM SYSTEMS
Database Design
1. Goal
Database design must support the target model:
Node
-> EdgeRuntime
-> CapabilityBinding
-> RuntimeBinding
-> Endpoint
It must also support:
- multi-tenant isolation.
- users and memberships.
- enrollment tokens.
- runtime catalog.
- install profiles.
- desired state versions.
- compiled runtime configurations.
- Traffic subscriptions.
- Traffic policies.
- domains and certificates.
- usage and quota.
- health and audit.
- billing.
2. Migration Policy
The model migration is breaking.
Rules:
- Use explicit SQL to migrate existing production data.
- Do not add application-level legacy fallback logic.
- Do not keep legacy columns after their data is migrated.
- Ent schema should represent the target model.
- Old
gateway_typevalues must become capability roles. - Old client configuration rows must become subscriptions.
- Existing runtime binding rows must point to Node and CapabilityBinding.
3. Technology
Primary database:
- MySQL 8 in current production.
- PostgreSQL remains supported by schema design where possible.
Database access:
- Ent schema in Control Plane.
- Runtime
Schema.Createmay create missing target structures in development, but production data migration must be explicit SQL.
Cache:
- Redis.
Metrics:
- Usage accounting is stored in relational tables.
- Prometheus integration is tracked separately for operational telemetry.
4. Naming
- table names use plural snake_case.
- primary keys use UUID string or database UUID depending on dialect.
- JSON fields use
_json. - tenant-scoped tables include
tenant_id. - tokens store only hashes.
- status fields use text with application-level constants.
- timestamp values are stored in UTC.
5. Core Tables
Target core tables:
tenants
users
memberships
nodes
edge_runtimes
deployment_tokens
capability_bindings
runtime_catalog
region_catalog_entries
runtime_install_profiles
runtime_bindings
endpoints
domains
certificates
endpoint_tls_bindings
desired_states
compiled_configurations
subscriptions
subscription_endpoints
traffic_policies
traffic_rules
traffic_usage_samples
traffic_usage_rollups
quota_policies
quota_enforcements
health_checks
audit_logs
6. Node Tables
nodes
Fields:
- id.
- tenant_id.
- name.
- source_type.
- ownership.
- provider.
- region.
- reported_address.
- public_address.
- private_address.
- mesh_address.
- reachability_json.
- status.
- attributes_json.
- last_seen_at.
- created_at.
- updated_at.
- deleted_at.
nodes.name is the operator-facing resource name.
nodes.provider is a stable infrastructure or network provider key. It is used by policy selectors, infrastructure placement, usage reporting, and future cost attribution. Examples: byoh, tencent, aws, oci, vultr.
nodes.region is a canonical deployment or network location key. It is used by policy selectors, localized client node naming, usage reporting, and future regional capacity views. Examples: hong-kong, tokyo, singapore, los-angeles, frankfurt.
Localized region labels, flags, cloud aliases, and stable ordering belong in the system-managed region_catalog_entries table. Provider region codes such as ap-east-1 are normalized to canonical keys such as hong-kong before Node or Deployment Token persistence.
nodes.attributes_json must not duplicate region presentation metadata.
region_catalog_entries
Fields:
- id.
- region_key.
- status.
- country_code.
- region_group.
- aliases.
- labels.
- sort_order.
- metadata.
- created_at.
- updated_at.
region_key is the unique canonical location identifier persisted by Node and Deployment Token records. country_code is ISO 3166-1 alpha-2 and is the source for flag generation. aliases contains provider-specific and historical inputs; an alias must resolve to exactly one canonical region. labels maps supported BCP 47 locales to display names. Region entries are system-managed seed data and can be extended without changing subscription renderers or Console forms.
edge_runtimes
Fields:
- id.
- node_id.
- installation_id.
- public_key.
- device_fingerprint_hash.
- identity_status.
- edge_runtime_version.
- status.
- last_enrolled_at.
- last_heartbeat_at.
- last_heartbeat_error.
- last_sync_error.
- created_at.
- updated_at.
7. Capability and Runtime Tables
capability_bindings
Fields:
- id.
- tenant_id.
- node_id.
- capability.
- role.
- status.
- values_json.
- readiness_json.
- created_at.
- updated_at.
- deleted_at.
Examples:
traffic.entry.traffic.exit.mesh.node.gateway.http.tunnel.endpoint.
runtime_bindings
Fields:
- id.
- tenant_id.
- node_id.
- capability_binding_id.
- runtime.
- role.
- status.
- values_json.
- runtime_version.
- install_state.
- last_apply_status.
- last_apply_error.
- created_at.
- updated_at.
- deleted_at.
runtime_catalog
Fields:
- kind.
- display_name.
- primary_capability.
- supported_capabilities_json.
- supported_roles_json.
- features_json.
- protocols_json.
- parameter_schema_json.
- field_metadata_json.
- binding_supported.
- adapter_status.
8. Endpoint and Certificate Tables
endpoints
Fields:
- id.
- tenant_id.
- node_id.
- capability_binding_id.
- runtime_binding_id.
- capability.
- role.
- protocol.
- address.
- domain_id.
- port.
- status.
- readiness_json.
- created_at.
- updated_at.
- deleted_at.
domains
Fields:
- id.
- tenant_id.
- name.
- scope.
- ownership_status.
- dns_status.
- provider.
- attributes_json.
- created_at.
- updated_at.
certificates
Fields:
- id.
- tenant_id.
- domain_id.
- scope.
- status.
- issuer.
- not_before.
- not_after.
- error.
- material_ref.
- created_at.
- updated_at.
endpoint_tls_bindings
Fields:
- id.
- tenant_id.
- endpoint_id.
- domain_id.
- certificate_id.
- tls_mode.
- sni.
- status.
- created_at.
- updated_at.
9. Subscription Tables
subscriptions
Fields:
- id.
- tenant_id.
- user_id.
- name.
- status.
- token_hash.
- format.
- credential_ref.
- endpoint_selection_json.
- quota_policy_id.
- last_used_at.
- created_at.
- updated_at.
- revoked_at.
- deleted_at.
subscription_endpoints
Fields:
- id.
- tenant_id.
- subscription_id.
- endpoint_id.
- created_at.
10. Desired State Tables
desired_states
Fields:
- id.
- tenant_id.
- node_id.
- version.
- spec_json.
- checksum.
- status.
- created_at.
Unique:
(node_id, version).
compiled_configurations
Fields:
- id.
- tenant_id.
- node_id.
- desired_state_id.
- runtime_binding_id.
- runtime.
- version.
- checksum.
- status.
- manifest_json.
- created_at.
- updated_at.
11. Traffic Usage Tables
traffic_usage_samples and traffic_usage_rollups must support:
- tenant_id.
- user_id.
- subscription_id.
- node_id.
- capability_binding_id.
- capability.
- role.
- runtime_binding_id.
- runtime.
- endpoint_id.
- direction.
- metering_point.
- total_bytes.
- uploaded_bytes.
- downloaded_bytes.
- reported_at.
12. SQL Migration Direction
Existing data migration should follow this direction:
- Create
nodesfrom existing generic host rows. - Create
capability_bindingsfrom old type values:ingress->traffic.entry.egress->traffic.exit.mixed-> bothtraffic.entryandtraffic.exitwhen applicable.
- Move existing runtime binding rows to
runtime_bindingswithnode_idandcapability_binding_id. - Move ingress endpoint rows to generic
endpointswithrole = traffic.entry. - Move certificate references to
endpoint_tls_bindings. - Move client configuration rows to
subscriptions. - Rename usage attribution fields from client configuration and gateway terms to subscription and node terms.
- Drop old columns and tables after data validation.
No application code should perform this backfill.
Current draft:
The draft must be reviewed against a production-like schema snapshot before execution.