feat(core): add ontology-backed asset and host runtime
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
begin;
|
||||
|
||||
alter table device_management_command_receipts
|
||||
drop constraint if exists device_management_command_receipts_command_kind_check;
|
||||
|
||||
alter table device_management_command_receipts
|
||||
add constraint device_management_command_receipts_command_kind_check
|
||||
check (command_kind in (
|
||||
'owner_scope.ensure',
|
||||
'project.ensure',
|
||||
'collection.ensure',
|
||||
'project_grant.upsert',
|
||||
'adapter_package.ensure',
|
||||
'adapter_version.register',
|
||||
'model_profile.register',
|
||||
'edge.ensure',
|
||||
'route.ensure',
|
||||
'enrollment_intent.ensure',
|
||||
'device.claim',
|
||||
'device.update',
|
||||
'device.transfer',
|
||||
'discovery.reject',
|
||||
'discovery.expire',
|
||||
'device_credential_binding.upsert',
|
||||
'device_credential_binding.revoke',
|
||||
'device_binding.ensure',
|
||||
'device_binding.revoke',
|
||||
'device_configuration_revision.create',
|
||||
'device_configuration_desired.set',
|
||||
'asset.ensure',
|
||||
'asset_binding.ensure',
|
||||
'asset_binding.close',
|
||||
'infrastructure_host.ensure',
|
||||
'infrastructure_endpoint.ensure',
|
||||
'infrastructure_deployment.ensure',
|
||||
'infrastructure_service_instance.ensure',
|
||||
'health_observation.record'
|
||||
));
|
||||
|
||||
create table if not exists device_assets (
|
||||
id uuid primary key,
|
||||
owner_scope_id uuid not null,
|
||||
project_id uuid not null,
|
||||
asset_key text not null
|
||||
check (asset_key ~ '^[a-z][a-z0-9-]{1,62}$'),
|
||||
display_name text not null
|
||||
check (length(btrim(display_name)) between 1 and 160),
|
||||
asset_type_ref text not null
|
||||
check (length(btrim(asset_type_ref)) between 3 and 256),
|
||||
lifecycle_state text not null default 'active'
|
||||
check (lifecycle_state in ('active', 'retired')),
|
||||
ontology_entity_id text not null default 'asset.asset'
|
||||
check (ontology_entity_id = 'asset.asset'),
|
||||
ontology_catalog_hash text not null default '229c61c02a790906'
|
||||
check (ontology_catalog_hash = '229c61c02a790906'),
|
||||
created_by_ref text not null
|
||||
check (length(btrim(created_by_ref)) between 3 and 256),
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (project_id, asset_key),
|
||||
unique (id, project_id, owner_scope_id),
|
||||
foreign key (project_id, owner_scope_id)
|
||||
references device_projects(id, owner_scope_id)
|
||||
);
|
||||
|
||||
create index if not exists device_assets_project_state_idx
|
||||
on device_assets (project_id, lifecycle_state, updated_at desc);
|
||||
|
||||
create table if not exists device_asset_bindings (
|
||||
id uuid primary key,
|
||||
owner_scope_id uuid not null,
|
||||
project_id uuid not null,
|
||||
binding_key text not null
|
||||
check (binding_key ~ '^[a-z][a-z0-9-]{1,62}$'),
|
||||
device_id uuid not null,
|
||||
asset_id uuid not null,
|
||||
binding_kind text not null default 'tracking'
|
||||
check (binding_kind in ('tracking', 'installed', 'assigned')),
|
||||
valid_from timestamptz not null,
|
||||
valid_to timestamptz,
|
||||
provenance_ref text not null
|
||||
check (length(btrim(provenance_ref)) between 3 and 256),
|
||||
ontology_entity_id text not null default 'device.asset_binding'
|
||||
check (ontology_entity_id = 'device.asset_binding'),
|
||||
ontology_catalog_hash text not null default '229c61c02a790906'
|
||||
check (ontology_catalog_hash = '229c61c02a790906'),
|
||||
created_by_ref text not null
|
||||
check (length(btrim(created_by_ref)) between 3 and 256),
|
||||
closed_by_ref text
|
||||
check (closed_by_ref is null or length(btrim(closed_by_ref)) between 3 and 256),
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (project_id, binding_key),
|
||||
foreign key (device_id, project_id, owner_scope_id)
|
||||
references device_instances(id, project_id, owner_scope_id),
|
||||
foreign key (asset_id, project_id, owner_scope_id)
|
||||
references device_assets(id, project_id, owner_scope_id),
|
||||
check (valid_to is null or valid_to > valid_from),
|
||||
check ((valid_to is null and closed_by_ref is null) or (valid_to is not null and closed_by_ref is not null))
|
||||
);
|
||||
|
||||
create unique index if not exists device_asset_bindings_active_device_idx
|
||||
on device_asset_bindings (device_id)
|
||||
where valid_to is null;
|
||||
|
||||
create index if not exists device_asset_bindings_asset_time_idx
|
||||
on device_asset_bindings (asset_id, valid_from desc, valid_to);
|
||||
|
||||
create table if not exists device_infrastructure_hosts (
|
||||
id uuid primary key,
|
||||
owner_scope_id uuid not null,
|
||||
project_id uuid not null,
|
||||
host_key text not null
|
||||
check (host_key ~ '^[a-z][a-z0-9-]{1,62}$'),
|
||||
display_name text not null
|
||||
check (length(btrim(display_name)) between 1 and 160),
|
||||
provider_ref text
|
||||
check (provider_ref is null or length(btrim(provider_ref)) between 3 and 256),
|
||||
external_ref text
|
||||
check (external_ref is null or length(btrim(external_ref)) between 3 and 256),
|
||||
management_credential_ref text
|
||||
check (
|
||||
management_credential_ref is null
|
||||
or management_credential_ref ~ '^secret-ref:[A-Za-z0-9][A-Za-z0-9._:/+-]{2,244}$'
|
||||
),
|
||||
lifecycle_state text not null default 'provisioning'
|
||||
check (lifecycle_state in ('provisioning', 'active', 'suspended', 'retired')),
|
||||
ontology_entity_id text not null default 'infrastructure.host'
|
||||
check (ontology_entity_id = 'infrastructure.host'),
|
||||
ontology_catalog_hash text not null default '229c61c02a790906'
|
||||
check (ontology_catalog_hash = '229c61c02a790906'),
|
||||
created_by_ref text not null
|
||||
check (length(btrim(created_by_ref)) between 3 and 256),
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (project_id, host_key),
|
||||
unique (id, project_id, owner_scope_id),
|
||||
foreign key (project_id, owner_scope_id)
|
||||
references device_projects(id, owner_scope_id)
|
||||
);
|
||||
|
||||
create index if not exists device_infrastructure_hosts_project_state_idx
|
||||
on device_infrastructure_hosts (project_id, lifecycle_state, updated_at desc);
|
||||
|
||||
create table if not exists device_infrastructure_endpoints (
|
||||
id uuid primary key,
|
||||
owner_scope_id uuid not null,
|
||||
project_id uuid not null,
|
||||
host_id uuid not null,
|
||||
endpoint_key text not null
|
||||
check (endpoint_key ~ '^[a-z][a-z0-9-]{1,62}$'),
|
||||
purpose text not null
|
||||
check (purpose in ('management', 'service', 'monitoring')),
|
||||
endpoint_uri text not null
|
||||
check (
|
||||
length(btrim(endpoint_uri)) between 8 and 512
|
||||
and endpoint_uri !~ '@'
|
||||
),
|
||||
lifecycle_state text not null default 'active'
|
||||
check (lifecycle_state in ('active', 'disabled', 'retired')),
|
||||
ontology_entity_id text not null default 'infrastructure.endpoint'
|
||||
check (ontology_entity_id = 'infrastructure.endpoint'),
|
||||
ontology_catalog_hash text not null default '229c61c02a790906'
|
||||
check (ontology_catalog_hash = '229c61c02a790906'),
|
||||
created_by_ref text not null
|
||||
check (length(btrim(created_by_ref)) between 3 and 256),
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (host_id, endpoint_key),
|
||||
unique (id, project_id, owner_scope_id),
|
||||
foreign key (host_id, project_id, owner_scope_id)
|
||||
references device_infrastructure_hosts(id, project_id, owner_scope_id)
|
||||
);
|
||||
|
||||
create table if not exists device_infrastructure_deployments (
|
||||
id uuid primary key,
|
||||
owner_scope_id uuid not null,
|
||||
project_id uuid not null,
|
||||
host_id uuid not null,
|
||||
deployment_key text not null
|
||||
check (deployment_key ~ '^[a-z][a-z0-9-]{1,62}$'),
|
||||
display_name text not null
|
||||
check (length(btrim(display_name)) between 1 and 160),
|
||||
artifact_ref text not null
|
||||
check (length(btrim(artifact_ref)) between 3 and 256),
|
||||
artifact_digest text not null
|
||||
check (artifact_digest ~ '^sha256:[a-f0-9]{64}$'),
|
||||
lifecycle_state text not null default 'desired'
|
||||
check (lifecycle_state in ('desired', 'applying', 'active', 'failed', 'retired')),
|
||||
ontology_entity_id text not null default 'infrastructure.deployment'
|
||||
check (ontology_entity_id = 'infrastructure.deployment'),
|
||||
ontology_catalog_hash text not null default '229c61c02a790906'
|
||||
check (ontology_catalog_hash = '229c61c02a790906'),
|
||||
created_by_ref text not null
|
||||
check (length(btrim(created_by_ref)) between 3 and 256),
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (project_id, deployment_key),
|
||||
unique (id, project_id, owner_scope_id),
|
||||
foreign key (host_id, project_id, owner_scope_id)
|
||||
references device_infrastructure_hosts(id, project_id, owner_scope_id)
|
||||
);
|
||||
|
||||
create table if not exists device_infrastructure_service_instances (
|
||||
id uuid primary key,
|
||||
owner_scope_id uuid not null,
|
||||
project_id uuid not null,
|
||||
host_id uuid not null,
|
||||
deployment_id uuid not null,
|
||||
edge_id uuid references device_edges(id),
|
||||
service_key text not null
|
||||
check (service_key ~ '^[a-z][a-z0-9-]{1,62}$'),
|
||||
display_name text not null
|
||||
check (length(btrim(display_name)) between 1 and 160),
|
||||
service_role text not null
|
||||
check (service_role ~ '^[a-z][a-z0-9._-]{1,63}$'),
|
||||
lifecycle_state text not null default 'provisioning'
|
||||
check (lifecycle_state in ('provisioning', 'active', 'degraded', 'stopped', 'retired')),
|
||||
ontology_entity_id text not null default 'infrastructure.service_instance'
|
||||
check (ontology_entity_id = 'infrastructure.service_instance'),
|
||||
ontology_catalog_hash text not null default '229c61c02a790906'
|
||||
check (ontology_catalog_hash = '229c61c02a790906'),
|
||||
created_by_ref text not null
|
||||
check (length(btrim(created_by_ref)) between 3 and 256),
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
unique (host_id, service_key),
|
||||
unique (id, project_id, owner_scope_id),
|
||||
foreign key (host_id, project_id, owner_scope_id)
|
||||
references device_infrastructure_hosts(id, project_id, owner_scope_id),
|
||||
foreign key (deployment_id, project_id, owner_scope_id)
|
||||
references device_infrastructure_deployments(id, project_id, owner_scope_id)
|
||||
);
|
||||
|
||||
create table if not exists device_health_observations (
|
||||
id uuid primary key,
|
||||
owner_scope_id uuid not null,
|
||||
project_id uuid not null,
|
||||
host_id uuid,
|
||||
service_instance_id uuid,
|
||||
observed_state text not null
|
||||
check (observed_state in ('reachable', 'degraded', 'unreachable')),
|
||||
evidence_class text not null
|
||||
check (evidence_class in ('agent_probe', 'channel', 'management_probe', 'manual')),
|
||||
source_ref text not null
|
||||
check (length(btrim(source_ref)) between 3 and 256),
|
||||
schema_ref text not null
|
||||
check (length(btrim(schema_ref)) between 3 and 256),
|
||||
evidence_projection jsonb not null default '{}'::jsonb
|
||||
check (
|
||||
jsonb_typeof(evidence_projection) = 'object'
|
||||
and octet_length(evidence_projection::text) <= 16384
|
||||
),
|
||||
observed_at timestamptz not null,
|
||||
expires_at timestamptz not null,
|
||||
ontology_entity_id text not null default 'observation.health_observation'
|
||||
check (ontology_entity_id = 'observation.health_observation'),
|
||||
ontology_catalog_hash text not null default '229c61c02a790906'
|
||||
check (ontology_catalog_hash = '229c61c02a790906'),
|
||||
recorded_by_ref text not null
|
||||
check (length(btrim(recorded_by_ref)) between 3 and 256),
|
||||
created_at timestamptz not null default now(),
|
||||
foreign key (project_id, owner_scope_id)
|
||||
references device_projects(id, owner_scope_id),
|
||||
foreign key (host_id, project_id, owner_scope_id)
|
||||
references device_infrastructure_hosts(id, project_id, owner_scope_id),
|
||||
foreign key (service_instance_id, project_id, owner_scope_id)
|
||||
references device_infrastructure_service_instances(id, project_id, owner_scope_id),
|
||||
check (
|
||||
(host_id is not null and service_instance_id is null)
|
||||
or (host_id is null and service_instance_id is not null)
|
||||
),
|
||||
check (expires_at > observed_at)
|
||||
);
|
||||
|
||||
create index if not exists device_health_observations_host_time_idx
|
||||
on device_health_observations (host_id, observed_at desc)
|
||||
where host_id is not null;
|
||||
|
||||
create index if not exists device_health_observations_service_time_idx
|
||||
on device_health_observations (service_instance_id, observed_at desc)
|
||||
where service_instance_id is not null;
|
||||
|
||||
commit;
|
||||
Reference in New Issue
Block a user