318 lines
13 KiB
SQL
318 lines
13 KiB
SQL
create extension if not exists pgcrypto;
|
|
create extension if not exists postgis;
|
|
|
|
create schema if not exists eventhub;
|
|
|
|
create table if not exists eventhub.event_source (
|
|
id integer generated always as identity primary key,
|
|
tenant_key text not null,
|
|
provider_key text not null,
|
|
source_kind text not null,
|
|
source_key text not null,
|
|
source_instance_key text not null default 'default',
|
|
tenant_provider_setting_key text,
|
|
external_fleet_key text,
|
|
created_at timestamptz not null default now(),
|
|
constraint ux_event_source unique (tenant_key, provider_key, source_kind, source_key, source_instance_key)
|
|
);
|
|
|
|
create table if not exists eventhub.import_run (
|
|
id uuid primary key,
|
|
tenant_key text not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
mode text not null,
|
|
status text not null,
|
|
refresh_master_data_first boolean not null default true,
|
|
source_group_type text,
|
|
source_group_entity_id text,
|
|
source_group_code text,
|
|
source_group_name text,
|
|
import_scope_type text not null,
|
|
root_source_org_entity_id text,
|
|
root_source_org_code text,
|
|
root_source_org_name text,
|
|
include_children boolean not null default false,
|
|
occurred_from timestamptz,
|
|
occurred_to timestamptz,
|
|
requested_event_families text[] not null default '{}',
|
|
acquisition_strategy text,
|
|
metadata jsonb not null default '{}'::jsonb,
|
|
planned_package_count integer not null default 0,
|
|
started_at timestamptz not null default now(),
|
|
finished_at timestamptz,
|
|
error_message text,
|
|
constraint chk_import_run_occ_time_order check (occurred_from is null or occurred_to is null or occurred_from < occurred_to)
|
|
);
|
|
|
|
create table if not exists eventhub.import_cursor (
|
|
id uuid primary key,
|
|
tenant_key text not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
scope_hash text not null,
|
|
event_family text not null,
|
|
source_kind text not null,
|
|
cursor_type text not null,
|
|
last_source_package_imported_at timestamptz,
|
|
last_source_package_id text,
|
|
last_source_row_updated_at timestamptz,
|
|
last_occurred_to timestamptz,
|
|
updated_at timestamptz not null default now(),
|
|
constraint ux_import_cursor unique (tenant_key, event_source_id, scope_hash, event_family, source_kind, cursor_type)
|
|
);
|
|
|
|
create table if not exists eventhub.data_package (
|
|
id uuid primary key,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
import_run_id uuid references eventhub.import_run(id),
|
|
tenant_key text not null,
|
|
package_key text not null,
|
|
package_type text not null,
|
|
status text not null,
|
|
source_group_type text,
|
|
source_group_entity_id text,
|
|
source_group_code text,
|
|
source_group_name text,
|
|
import_scope_type text,
|
|
root_source_org_entity_id text,
|
|
root_source_org_code text,
|
|
root_source_org_name text,
|
|
include_children boolean not null default false,
|
|
occurred_from timestamptz,
|
|
occurred_to timestamptz,
|
|
event_family text,
|
|
business_date date,
|
|
external_package_id text,
|
|
extraction_code text,
|
|
extraction_source_kind text,
|
|
entity_axis text,
|
|
batch_no integer,
|
|
chunk_from timestamptz,
|
|
chunk_to timestamptz,
|
|
source_package_kind text,
|
|
source_package_id text,
|
|
source_package_entity_id text,
|
|
source_package_period_from timestamptz,
|
|
source_package_period_to timestamptz,
|
|
source_package_imported_at timestamptz,
|
|
received_at timestamptz not null default now(),
|
|
completed_at timestamptz,
|
|
event_count integer not null default 0,
|
|
metadata jsonb not null default '{}'::jsonb,
|
|
error_message text,
|
|
constraint ux_data_package_package_key unique (tenant_key, event_source_id, package_key),
|
|
constraint chk_data_package_occ_time_order check (occurred_from is null or occurred_to is null or occurred_from < occurred_to),
|
|
constraint chk_data_package_chunk_time_order check (chunk_from is null or chunk_to is null or chunk_from < chunk_to)
|
|
);
|
|
|
|
create table if not exists eventhub.source_master_entity (
|
|
id uuid primary key,
|
|
tenant_key text not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
entity_type text not null,
|
|
source_entity_id text not null,
|
|
source_external_key text,
|
|
display_name text,
|
|
active boolean,
|
|
valid_from timestamptz,
|
|
valid_to timestamptz,
|
|
source_updated_at timestamptz,
|
|
payload jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
constraint ux_source_master_entity unique (tenant_key, event_source_id, entity_type, source_entity_id),
|
|
constraint chk_source_master_entity_valid_time_order check (valid_from is null or valid_to is null or valid_from <= valid_to)
|
|
);
|
|
|
|
create table if not exists eventhub.source_master_relation (
|
|
id uuid primary key,
|
|
tenant_key text not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
relation_key text not null,
|
|
relation_type text not null,
|
|
from_entity_type text not null,
|
|
from_source_entity_id text not null,
|
|
to_entity_type text not null,
|
|
to_source_entity_id text not null,
|
|
valid_from timestamptz,
|
|
valid_to timestamptz,
|
|
source_updated_at timestamptz,
|
|
payload jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
constraint ux_source_master_relation unique (tenant_key, event_source_id, relation_key),
|
|
constraint chk_source_master_relation_valid_time_order check (valid_from is null or valid_to is null or valid_from <= valid_to)
|
|
);
|
|
|
|
create table if not exists eventhub.vehicle (
|
|
id uuid primary key,
|
|
tenant_key text not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
source_vehicle_entity_id text,
|
|
vin text,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
create table if not exists eventhub.vehicle_registration (
|
|
id uuid primary key,
|
|
tenant_key text not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
source_registration_entity_id text,
|
|
nation text not null,
|
|
registration_number text not null,
|
|
source_updated_at timestamptz,
|
|
payload jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
create table if not exists eventhub.vehicle_registration_assignment (
|
|
id uuid primary key,
|
|
tenant_key text not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
vehicle_registration_id uuid not null references eventhub.vehicle_registration(id) on delete cascade,
|
|
vehicle_id uuid not null references eventhub.vehicle(id) on delete cascade,
|
|
valid_from timestamptz,
|
|
valid_to timestamptz,
|
|
source_updated_at timestamptz,
|
|
payload jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now(),
|
|
constraint chk_vehicle_registration_assignment_valid_time_order check (valid_from is null or valid_to is null or valid_from <= valid_to)
|
|
);
|
|
|
|
create table if not exists eventhub.event (
|
|
id uuid not null,
|
|
event_source_id integer not null references eventhub.event_source(id),
|
|
data_package_id uuid not null references eventhub.data_package(id),
|
|
external_source_event_id text not null,
|
|
driver_entity_id uuid references eventhub.source_master_entity(id),
|
|
vehicle_id uuid references eventhub.vehicle(id),
|
|
vehicle_registration_id uuid references eventhub.vehicle_registration(id),
|
|
source_package_entity_id uuid references eventhub.source_master_entity(id),
|
|
occurred_at timestamptz not null,
|
|
received_partner_at timestamptz,
|
|
received_hub_at timestamptz not null default now(),
|
|
event_domain text not null,
|
|
event_type text not null,
|
|
lifecycle text not null,
|
|
odometer_m bigint,
|
|
position geography(Point, 4326),
|
|
payload jsonb not null default '{}'::jsonb,
|
|
manual_entry boolean not null default false,
|
|
source_record_key_hash text not null,
|
|
event_signature_hash text,
|
|
created_at timestamptz not null default now(),
|
|
constraint pk_event primary key (occurred_at, id),
|
|
constraint chk_event_driver_or_vehicle_ref check (
|
|
driver_entity_id is not null
|
|
or vehicle_id is not null
|
|
or vehicle_registration_id is not null
|
|
)
|
|
);
|
|
|
|
create table if not exists eventhub.event_detail (
|
|
event_occurred_at timestamptz not null,
|
|
event_id uuid not null,
|
|
detail_type text not null,
|
|
attributes jsonb not null default '{}'::jsonb,
|
|
created_at timestamptz not null default now(),
|
|
constraint pk_event_detail primary key (event_occurred_at, event_id, detail_type),
|
|
constraint fk_event_detail_event foreign key (event_occurred_at, event_id)
|
|
references eventhub.event(occurred_at, id)
|
|
on delete cascade
|
|
);
|
|
|
|
create unique index if not exists ux_event_source_record
|
|
on eventhub.event(source_record_key_hash);
|
|
|
|
create index if not exists idx_event_signature
|
|
on eventhub.event(event_signature_hash)
|
|
where event_signature_hash is not null;
|
|
|
|
create index if not exists idx_event_source_time
|
|
on eventhub.event(event_source_id, occurred_at desc);
|
|
|
|
create index if not exists idx_event_package_time
|
|
on eventhub.event(data_package_id, occurred_at desc);
|
|
|
|
create index if not exists idx_event_domain_type_time
|
|
on eventhub.event(event_domain, event_type, occurred_at desc);
|
|
|
|
create index if not exists idx_event_driver_time
|
|
on eventhub.event(driver_entity_id, occurred_at desc)
|
|
where driver_entity_id is not null;
|
|
|
|
create index if not exists idx_event_vehicle_time
|
|
on eventhub.event(vehicle_id, occurred_at desc)
|
|
where vehicle_id is not null;
|
|
|
|
create index if not exists idx_event_vehicle_registration_time
|
|
on eventhub.event(vehicle_registration_id, occurred_at desc)
|
|
where vehicle_registration_id is not null;
|
|
|
|
create index if not exists idx_event_position_gist
|
|
on eventhub.event using gist(position)
|
|
where position is not null;
|
|
|
|
create index if not exists idx_event_payload_gin
|
|
on eventhub.event using gin(payload);
|
|
|
|
create index if not exists idx_event_detail_type
|
|
on eventhub.event_detail(detail_type);
|
|
|
|
create index if not exists idx_event_detail_attributes_gin
|
|
on eventhub.event_detail using gin(attributes);
|
|
|
|
create index if not exists idx_source_master_entity_type_key
|
|
on eventhub.source_master_entity(tenant_key, event_source_id, entity_type, source_external_key)
|
|
where source_external_key is not null;
|
|
|
|
create index if not exists idx_source_master_entity_payload_gin
|
|
on eventhub.source_master_entity using gin(payload);
|
|
|
|
create index if not exists idx_source_master_relation_from
|
|
on eventhub.source_master_relation(tenant_key, event_source_id, from_entity_type, from_source_entity_id, relation_type);
|
|
|
|
create index if not exists idx_source_master_relation_to
|
|
on eventhub.source_master_relation(tenant_key, event_source_id, to_entity_type, to_source_entity_id, relation_type);
|
|
|
|
create index if not exists idx_source_master_relation_payload_gin
|
|
on eventhub.source_master_relation using gin(payload);
|
|
|
|
create index if not exists idx_vehicle_lookup_ctx
|
|
on eventhub.vehicle(tenant_key, event_source_id, updated_at desc);
|
|
|
|
create index if not exists idx_vehicle_source_entity
|
|
on eventhub.vehicle(tenant_key, event_source_id, source_vehicle_entity_id)
|
|
where source_vehicle_entity_id is not null;
|
|
|
|
create index if not exists idx_vehicle_vin
|
|
on eventhub.vehicle(tenant_key, event_source_id, vin)
|
|
where vin is not null;
|
|
|
|
create index if not exists idx_vehicle_registration_source_entity
|
|
on eventhub.vehicle_registration(tenant_key, event_source_id, source_registration_entity_id)
|
|
where source_registration_entity_id is not null;
|
|
|
|
create index if not exists idx_vehicle_registration_plate
|
|
on eventhub.vehicle_registration(tenant_key, event_source_id, nation, registration_number);
|
|
|
|
create index if not exists idx_vehicle_registration_assignment_registration_time
|
|
on eventhub.vehicle_registration_assignment(vehicle_registration_id, valid_from desc, valid_to);
|
|
|
|
create index if not exists idx_vehicle_registration_assignment_vehicle_time
|
|
on eventhub.vehicle_registration_assignment(vehicle_id, valid_from desc, valid_to);
|
|
|
|
create index if not exists idx_data_package_source_time
|
|
on eventhub.data_package(tenant_key, event_source_id, received_at desc);
|
|
|
|
create index if not exists idx_data_package_scope
|
|
on eventhub.data_package(tenant_key, import_scope_type, root_source_org_entity_id, occurred_from, occurred_to);
|
|
|
|
create index if not exists idx_data_package_extraction
|
|
on eventhub.data_package(tenant_key, event_source_id, import_run_id, event_family, extraction_source_kind, extraction_code, batch_no);
|
|
|
|
create index if not exists idx_import_run_source_status
|
|
on eventhub.import_run(tenant_key, event_source_id, status, started_at desc);
|