# Слой сырых данных

Слой Raw data содержит 3 отдельные схемы данных, каждая из которых отвечает за различные аспекты платформы телематики и бизнес-аналитики:

* [`raw_business_data`](#raw_business_data-structure) - содержит таблицы, атрибуты и значения, связанные с бизнес-информацией, такой как транспортные средства, сотрудники, геозоны, добавленные пользователями, и т. д.
* [`raw_telematics_data`](#raw_telematics_data-structure) - содержит таблицы, атрибуты и значения, связанные с телематическими данными, передаваемыми с устройств под мониторингом, такими как местоположения, входы, выходы и события.
* [`repo`](#repo-data-structure) - содержит таблицы для управления активами и инвентарем, включая настраиваемые типы активов, пользовательские поля, связи между активами и геопространственные данные для отслеживания ресурсов организации.

Каждая схема оптимизирована под свой домен данных и характер доступа, обеспечивая полное покрытие потребностей в операционном управлении, телематике и управлении активами.

## `raw_business_data` структура

Эта схема содержит более 40 тщательно отобранных таблиц, охватывающих различные бизнес-аспекты и варианты использования. Эти таблицы представляют ваши ключевые бизнес-сущности, организационную структуру и операционные данные.

<figure><img src="/files/223cc9dfd17ee9bdd4164e855310cbb01bd264ac" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Интерактивная диаграмма схемы raw\_business\_data доступна на **dbdiagram.io**: <https://dbdiagram.io/d/V3-bronze-layer-68ecfd1c2e68d21b4131089a>
{% endhint %}

Сведения о схеме raw business data приведены ниже.

{% code title="схема raw\_business\_data" expandable="true" %}

```sql
Table "vehicle_service_tasks" {
  "record_added_at" timestamp [not null]
  "start_mileage" numeric
  "comment" "character varying(255)"
  "status" "character varying(10)" [not null]
  "completion_date" timestamp
  "start_engine_hours" numeric
  "service_task_id" integer [not null]
  "is_notification_push_enabled" boolean [not null]
  "date_notification_interval" interval
  "predicted_datetime" timestamp
  "cost" numeric [not null]
  "mileage_limit" numeric
  "notification_emails" text
  "is_unplanned" boolean [not null]
  "is_repeat" boolean [not null]
  "completion_engine_hours" integer
  "engine_hours_limit" numeric
  "mileage_repeat_interval" integer
  "vehicle_id" integer [not null]
  "engine_hours_notification_interval" integer
  "start_date" timestamp
  "mileage_notification_interval" integer
  "date_repeat_interval" interval
  "description" "character varying(255)"
  "notification_sms_phone_numbers" text
  "end_date" timestamp
  "engine_hours_repeat_interval" integer
  "completion_mileage" integer
}

Table "garages" {
  "record_added_at" timestamp [not null]
  "garage_id" integer [not null]
  "longitude" numeric
  "mechanic_name" "character varying(255)"
  "radius" integer [not null]
  "latitude" numeric
  "organization_label" "character varying(255)"
  "user_id" integer [not null]
  "dispatcher_name" "character varying(255)"
  "address" "character varying(255)"
}

Table "driver_history" {
  "server_datetime" timestamp [not null]
  "address" "character varying(255)"
  "updated_by" integer [not null]
  "object_id" integer
  "longitude" numeric
  "latitude" numeric
  "driver_history_id" integer [not null]
  "hardware_key" "character varying(64)"
  "new_employee_id" integer
  "changed_datetime" timestamp
  "record_added_at" timestamp [not null]
  "old_employee_id" integer
}

Table "departments" {
  "record_added_at" timestamp [not null]
  "department_label" "character varying(255)" [not null]
  "latitude" numeric
  "department_id" integer [not null]
  "address" "character varying(255)"
  "radius" integer [not null]
  "longitude" numeric
  "user_id" integer [not null]
}

Table "checkins" {
  "radius" integer [not null]
  "latitude" numeric [not null]
  "employee_id" integer [not null]
  "longitude" numeric [not null]
  "record_added_at" timestamp [not null]
  "actual_datetime" timestamp [not null]
  "user_id" integer [not null]
  "form_id" integer [not null]
  "address" "character varying(255)"
  "planned_datetime" timestamp [not null]
  "object_id" integer [not null]
  "checkin_id" integer [not null]
  "comment" text
}

Table "statuses" {
  "order_sort" integer [not null]
  "listing_id" integer [not null]
  "color" "character varying(6)" [not null]
  "status_id" integer [not null]
  "status_label" "character varying(200)" [not null]
  "record_added_at" timestamp [not null]
  "is_deleted" boolean [not null]
}

Table "places_linked_entity_fields" {
  "value" bigint [not null]
  "record_added_at" timestamp [not null]
  "place_id" integer [not null]
  "field_id" integer [not null]
}

Table "places_text_fields" {
  "place_id" integer [not null]
  "record_added_at" timestamp [not null]
  "value" text [not null]
  "field_id" integer [not null]
}

Table "users2zones" {
  "zone_id" integer [not null]
  "record_added_at" timestamp [not null]
  "user_id" integer [not null]
}

Table "objects" {
  "record_added_at" timestamp [not null]
  "create_datetime" timestamp [not null]
  "client_id" integer [not null]
  "group_id" integer
  "object_label" "character varying(100)"
  "model" "character varying(64)"
  "is_clone" boolean [not null]
  "is_deleted" boolean [not null]
  "device_id" integer [not null]
  "object_id" integer [not null]
}

Table "device_output_name" {
  "device_id" integer [not null]
  "record_added_at" timestamp [not null]
  "label" "character varying(100)" [not null]
  "number" integer [not null]
}

Table "geofence_points" {
  "longitude" numeric [not null]
  "number" integer [not null]
  "zone_id" integer [not null]
  "record_added_at" timestamp [not null]
  "latitude" numeric [not null]
}

Table "custom_fields" {
  "record_added_at" timestamp [not null]
  "entity_id" integer [not null]
  "is_required" boolean [not null]
  "custom_field_label" text [not null]
  "parameters" jsonb
  "custom_field_type" integer [not null]
  "description" text
  "custom_field_id" integer [not null]
}

Table "places_decimal_fields" {
  "field_id" integer [not null]
  "record_added_at" timestamp [not null]
  "place_id" integer [not null]
  "value" numeric [not null]
}

Table "task_history" {
  "task_id" integer [not null]
  "activity" integer [not null]
  "task_history_id" integer [not null]
  "record_added_at" timestamp [not null]
  "user_id" integer [not null]
  "event_datetime" timestamp [not null]
  "payload" text
}

Table "tags" {
  "tag_label" "character varying(64)" [not null]
  "color" "character varying(6)"
  "user_id" integer [not null]
  "record_added_at" timestamp [not null]
  "tag_id" integer [not null]
}

Table "places" {
  "description" text
  "custom_fields" jsonb
  "place_id" integer [not null]
  "external_id" "character varying(32)"
  "record_added_at" timestamp [not null]
  "user_id" integer
  "latitude" numeric
  "radius" integer
  "place_label" "character varying(256)"
  "assigned_datetime" timestamp
  "address" "character varying(256)"
  "longitude" numeric
}

Table "status_listings" {
  "user_id" integer [not null]
  "is_supervisor_controlled" boolean [not null]
  "is_deleted" boolean [not null]
  "status_listing_id" integer [not null]
  "is_employee_controlled" boolean [not null]
  "record_added_at" timestamp [not null]
  "status_listing_label" "character varying(200)" [not null]
}

Table "models" {
  "record_added_at" timestamp [not null]
  "model_id" integer [not null]
  "has_battery_level" boolean [not null]
  "alternative_label" "character varying(50)" [not null]
  "vendor" "character varying(30)" [not null]
  "is_clone" boolean
  "has_altitude" boolean [not null]
  "has_phone" boolean [not null]
  "type_output_control" "character varying(30)" [not null]
  "has_gsm_roaming" boolean [not null]
  "has_gsm_level" boolean [not null]
  "model" "character varying(255)" [not null]
  "type_special_control" "character varying(255)" [not null]
  "digital_amount" integer [not null]
  "has_detach_button" boolean [not null]
  "has_gsm_name" boolean [not null]
  "analog_amount" integer [not null]
  "outputs_amount" integer [not null]
}

Table "vehicle_trackers_history" {
  "vehicle_id" integer [not null]
  "record_added_at" timestamp [not null]
  "object_id" integer [not null]
  "changed_datetime" timestamp [not null]
  "vehicle_tracker_history_id" integer [not null]
}

Table "groups" {
  "group_id" integer [not null]
  "group_color" "character varying(6)" [not null]
  "group_label" "character varying(255)" [not null]
  "client_id" integer [not null]
  "record_added_at" timestamp [not null]
}

Table "sensor_description" {
  "record_added_at" timestamp [not null]
  "parameters" jsonb
  "input_id" integer [not null]
  "accuracy" numeric [not null]
  "sensor_units" "character varying(10)"
  "multiplier" doubleprecision [not null]
  "input_label" "character varying(64)"
  "sensor_label" "character varying(100)"
  "units_type" integer [not null]
  "divider" doubleprecision [not null]
  "group_id" integer [not null]
  "sensor_id" integer [not null]
  "device_id" integer [not null]
  "sensor_type" "character varying(45)" [not null]
  "group_type" integer [not null]
  "calibration_data" jsonb
}

Table "entities" {
  "entity_label" jsonb
  "record_added_at" timestamp [not null]
  "entity_id" integer [not null]
  "builtin_type" integer [not null]
  "user_id" integer [not null]
}

Table "zones" {
  "address" "character varying(255)"
  "radius" integer [not null]
  "zone_id" integer [not null]
  "circle_center_latitude" numeric [not null]
  "client_id" integer [not null]
  "zone_label" "character varying(100)"
  "color" "character varying(6)" [not null]
  "zone_type" "character varying(20)" [not null]
  "circle_center_longitude" numeric [not null]
  "latitude" numeric [not null]
  "record_added_at" timestamp [not null]
  "longitude" numeric [not null]
}

Table "vehicles" {
  "vehicle_id" integer [not null]
  "payload_length" numeric
  "vin" "character varying(20)"
  "free_insurance_policy_number" "character varying(50)"
  "vehicle_label" "character varying(100)"
  "payload_width" numeric
  "color" "character varying(6)"
  "trailer" "character varying(255)"
  "object_id" integer
  "vehicle_status_id" integer
  "liability_insurance_valid_till" timestamp
  "manufacture_year" integer
  "fuel_grade" "character varying(16)"
  "fuel_cost" numeric
  "fuel_tank_volume" numeric
  "model" "character varying(100)"
  "garage_id" integer
  "payload_height" numeric
  "max_speed" numeric
  "registration_number" "character varying(32)"
  "tyre_size" "character varying(50)"
  "passenger_capacity" integer
  "record_added_at" timestamp [not null]
  "trailer_reg_number" "character varying(32)"
  "free_insurance_valid_till_date" timestamp
  "gross_weight" numeric
  "standard_fuel_consumption" numeric
  "fuel_type" integer
  "payload_weight" numeric
  "additional_info" text
  "vehicle_subtype" "character varying(32)"
  "liability_insurance_policy_number" "character varying(50)"
  "frame_number" "character varying(32)"
  "user_id" integer [not null]
  "vehicle_type" integer [not null]
  "chassis_number" "character varying(32)"
  "tyres_number" integer
  "wheel_arrangement" "character varying(16)"
}

Table "tag_links" {
  "entity_id" integer [not null]
  "record_added_at" timestamp [not null]
  "entity_type" integer [not null]
  "ordinal" integer [not null]
  "tag_id" integer [not null]
}

Table "rules" {
  "rule_id" integer [not null]
  "object_id" integer [not null]
  "parameters" jsonb
  "alert_phone" "character varying(210)" [not null]
  "event_type" "character varying(100)" [not null]
  "client_id" integer [not null]
  "is_push_enabled" boolean [not null]
  "event_comment1" "character varying(255)" [not null]
  "event_label" "character varying(255)" [not null]
  "description" "character varying(255)" [not null]
  "record_added_at" timestamp [not null]
  "alert_sms" text [not null]
  "event_group" integer [not null]
  "created_at" timestamp [not null]
  "maximum" integer [not null]
  "is_deleted" boolean [not null]
  "alert_email" text [not null]
  "event_comment2" "character varying(255)" [not null]
}

Table "status_history" {
  "longitude" numeric
  "new_status_id" integer
  "status_history_id" integer [not null]
  "device_id" integer [not null]
  "updated_by" integer [not null]
  "address" "character varying(255)"
  "latitude" numeric
  "record_added_at" timestamp [not null]
  "server_datetime" timestamp [not null]
  "changed_datetime" timestamp
  "old_status_id" integer
}

Table "rules2zones" {
  "zone_id" integer [not null]
  "record_added_at" timestamp [not null]
  "rule_id" integer [not null]
}

Table "forms" {
  "object_id" integer [not null]
  "description" text
  "form_label" "character varying(255)" [not null]
  "fields" text
  "created_at" timestamp [not null]
  "submission_address" "character varying(255)"
  "submission_latitude" numeric
  "form_id" integer [not null]
  "submission_longitude" numeric
  "is_submission_in_zone" boolean [not null]
  "values" text
  "record_added_at" timestamp [not null]
  "task_id" integer
  "submitted_at" timestamp
}


Table "rules2objects" {
  "object_params" jsonb
  "param_group_number" integer [not null]
  "object_id" integer [not null]
  "record_added_at" timestamp [not null]
  "rule_id" integer [not null]
}

Table "tasks" {
  "time_from" timestamp
  "stay_duration_minutes" interval
  "external_id" "character varying(100)"
  "object_id" integer
  "task_type" integer
  "arrival_duration_minutes" interval
  "status" integer
  "arrival_datetime" timestamp
  "record_added_at" timestamp [not null]
  "task_id" integer [not null]
  "user_id" integer
  "status_change_datetime" timestamp
  "order_sort" integer
  "time_to" timestamp
  "max_delay_minuts" integer
  "is_stay_control_enabled" boolean
  "address" "character varying(255)"
  "task_label" "character varying(200)" [not null]
  "longitude" numeric
  "created_by" integer
  "description" text [not null]
  "radius" integer
  "latitude" numeric
  "stay_duration" integer
  "created_at" timestamp [not null]
  "custom_fields" jsonb
  "parent_task_id" integer
}

Table "places_bigint_fields" {
  "field_id" integer [not null]
  "value" bigint [not null]
  "place_id" integer [not null]
  "record_added_at" timestamp [not null]
}

Table "devices" {
  "is_sim_blocked" boolean [not null]
  "device_id" integer [not null]
  "device_imei" "character varying(64)" [not null]
  "network_label" "character varying(50)" [not null]
  "status_listing_id" integer [not null]
  "signal_level" numeric [not null]
  "phone" "character varying(32)" [not null]
  "has_roaming" boolean [not null]
  "created_at" timestamp [not null]
  "owner_id" integer [not null]
  "record_added_at" timestamp [not null]
}

Table "description_parameters" {
  "description" "character varying(150)"
  "record_added_at" timestamp [not null]
  "type" "character varying(100)" [not null]
  "key" integer [not null]
}

Table "users" {
  "company_label" "character varying(255)" [not null]
  "registration_datetime" timestamp
  "first_name" "character varying(100)" [not null]
  "master_id" integer
  "last_name" "character varying(100)" [not null]
  "birth_date" timestamp
  "timezone_label" "character varying(30)"
  "middle_name" "character varying(100)" [not null]
  "user_id" integer [not null]
  "locale" "character varying(10)" [not null]
  "record_added_at" timestamp [not null]
}

Table "counters" {
  "sensor_id" integer
  "multiplier" numeric [not null]
  "counter_id" integer [not null]
  "device_id" integer [not null]
  "counter_type" integer [not null]
  "record_added_at" timestamp [not null]
}

Table "employees" {
  "driver_license_valid_till" timestamp
  "record_added_at" timestamp [not null]
  "last_name" "character varying(100)"
  "department_id" integer
  "citizen_id_number" "character varying(32)"
  "first_name" "character varying(100)"
  "driver_license_categories" "character varying(32)"
  "user_id" integer [not null]
  "phone_number" "character varying(32)"
  "object_id" integer
  "is_deleted" boolean [not null]
  "driver_license_issue_date" boolean
  "hardware_key" "character varying(64)"
  "middle_name" "character varying(100)"
  "address" "character varying(255)"
  "latitude" numeric
  "employee_id" integer [not null]
  "personnel_number" "character varying(15)"
  "fuel_cost" doubleprecision
  "driver_license_number" "character varying(32)"
  "email" "character varying(100)"
  "fuel_consumption" doubleprecision
  "radius" integer [not null]
  "longitude" numeric
}

Table "places_longtext_fields" {
  "field_id" integer [not null]
  "value" text [not null]
  "record_added_at" timestamp [not null]
  "place_id" integer [not null]
}

Table "groups_objects" {
  "groups_client_id" integer
  "objects_client_id" integer

  Indexes {
    (groups_client_id, objects_client_id) [pk]
  }
}

Table "device_settings" {
  "device_id" integer [not null]
  "key" "character varying" [not null]
  "value" text

  Indexes {
    (device_id, key) [pk]
  }
}

Table "event_description" {
  "event_id" integer [not null, pk]
  "description" text
}

Ref:"employees"."employee_id" < "checkins"."employee_id"

Ref:"objects"."object_id" < "checkins"."object_id"

Ref:"forms"."form_id" < "checkins"."form_id"

Ref:"sensor_description"."sensor_id" < "counters"."sensor_id"

Ref:"devices"."device_id" < "counters"."device_id"

Ref:"entities"."entity_id" < "custom_fields"."entity_id"

Ref:"departments"."department_id" < "employees"."department_id"

Ref:"users"."user_id" < "departments"."user_id"

Ref:"description_parameters"."key" < "counters"."counter_type"

Ref:"description_parameters"."key" < "custom_fields"."custom_field_type"

Ref:"description_parameters"."key" < "driver_history"."updated_by"

Ref:"description_parameters"."key" < "entities"."builtin_type"

Ref:"description_parameters"."key" < "sensor_description"."units_type"

Ref:"description_parameters"."key" < "status_history"."updated_by"

Ref:"description_parameters"."key" < "tasks"."status"

Ref:"description_parameters"."key" < "tasks"."created_at"

Ref:"description_parameters"."key" < "tasks"."task_type"

Ref:"description_parameters"."key" < "vehicles"."fuel_type"

Ref:"description_parameters"."key" < "task_history"."activity"

Ref:"description_parameters"."key" < "sensor_description"."group_type"

Ref:"devices"."device_id" < "device_output_name"."device_id"

Ref:"status_listings"."status_listing_id" < "devices"."status_listing_id"

Ref:"employees"."employee_id" < "driver_history"."new_employee_id"

Ref:"employees"."employee_id" < "driver_history"."old_employee_id"

Ref:"objects"."object_id" < "driver_history"."object_id"

Ref:"objects"."object_id" < "employees"."object_id"

Ref:"users"."user_id" < "employees"."user_id"

Ref:"users"."user_id" < "entities"."user_id"

Ref:"tasks"."task_id" < "forms"."task_id"

Ref:"objects"."object_id" < "forms"."object_id"

Ref:"objects"."object_id" < "tasks"."object_id"

Ref:"users"."user_id" < "garages"."user_id"

Ref:"groups"."client_id" < "groups_objects"."groups_client_id"

Ref:"objects"."client_id" < "groups_objects"."objects_client_id"

Ref:"models"."model" < "objects"."model"

Ref:"devices"."device_id" < "objects"."device_id"

Ref:"users"."user_id" < "places"."user_id"

Ref:"custom_fields"."custom_field_id" < "places_bigint_fields"."field_id"

Ref:"places"."place_id" < "places_bigint_fields"."place_id"

Ref:"custom_fields"."custom_field_id" < "places_decimal_fields"."field_id"

Ref:"places"."place_id" < "places_decimal_fields"."place_id"

Ref:"custom_fields"."custom_field_id" < "places_linked_entity_fields"."field_id"

Ref:"places"."place_id" < "places_linked_entity_fields"."place_id"

Ref:"custom_fields"."custom_field_id" < "places_longtext_fields"."field_id"

Ref:"places"."place_id" < "places_longtext_fields"."place_id"

Ref:"custom_fields"."custom_field_id" < "places_text_fields"."field_id"

Ref:"places"."place_id" < "places_text_fields"."place_id"

Ref:"rules"."rule_id" < "rules2zones"."rule_id"

Ref:"objects"."object_id" < "rules2objects"."object_id"

Ref:"rules"."rule_id" < "rules2objects"."object_id"

Ref:"zones"."zone_id" < "rules2zones"."zone_id"

Ref:"devices"."device_id" < "sensor_description"."device_id"

Ref:"statuses"."status_id" < "status_history"."new_status_id"

Ref:"statuses"."status_id" < "status_history"."old_status_id"

Ref:"devices"."device_id" < "status_history"."device_id"

Ref:"users"."user_id" < "status_listings"."user_id"

Ref:"status_listings"."status_listing_id" < "statuses"."listing_id"

Ref:"tags"."tag_id" < "tag_links"."tag_id"

Ref:"users"."user_id" < "tags"."user_id"

Ref:"tasks"."task_id" < "task_history"."task_id"

Ref:"users"."user_id" < "task_history"."user_id"

Ref:"tasks"."parent_task_id" < "tasks"."task_id"

Ref:"users"."user_id" < "tasks"."user_id"

Ref:"users"."master_id" < "users"."user_id"

Ref:"users"."user_id" < "users2zones"."user_id"

Ref:"zones"."zone_id" < "users2zones"."zone_id"

Ref:"vehicles"."vehicle_id" < "vehicle_service_tasks"."vehicle_id"

Ref:"objects"."object_id" < "vehicle_trackers_history"."object_id"

Ref:"vehicles"."vehicle_id" < "vehicle_trackers_history"."vehicle_id"

Ref:"garages"."garage_id" < "vehicles"."garage_id"

Ref:"objects"."object_id" < "vehicles"."object_id"

Ref:"users"."user_id" < "vehicles"."user_id"

Ref:"zones"."zone_id" < "geofence_points"."zone_id"

Ref:"users"."user_id" < "devices"."owner_id"

Ref:"users"."user_id" < "objects"."client_id"

```

{% endcode %}

### Частота обновления

Данные в этой схеме синхронизируются с основной БД. Обновления выполняются инкрементально по мере появления изменений в исходной базе данных MySQL, как правило, с задержкой менее 5 минут после изменения в источнике.

### `description_parameters`

Система включает справочные данные для стандартизации значений по всей базе данных:

<table><thead><tr><th width="167.1817626953125">Тип справочника</th><th width="173.9090576171875">Описание</th><th>Пример значений</th></tr></thead><tbody><tr><td>Определения типов</td><td>Стандартные типы сущностей</td><td><code>vehicle_type: car, truck, bus</code></td></tr><tr><td>Коды статусов</td><td>Значения статусов задач и системы</td><td><code>tasks_status: unassigned, assigned, done</code></td></tr><tr><td>Определения единиц</td><td>Единицы измерения для датчиков</td><td><code>units_type: liter, gallon, celsius</code></td></tr><tr><td>Классификации сущностей</td><td>Категории бизнес-сущностей</td><td><code>entities_type: place, task, customer</code></td></tr></tbody></table>

### Ключевые таблицы по категориям

Таблицы в **`raw_business_data`** схеме сгруппированы по функциональным категориям для более удобной навигации. В таблице ниже приведены ключевые таблицы по их бизнес-назначению:

Основные бизнес-сущности

<details>

<summary><strong><code>users</code></strong></summary>

**Описание**: Учетные записи пользователей, содержащие сведения профиля, принадлежность к компании, настройки локализации (часовой пояс, локаль) и иерархические связи через master\_id для многоуровневых структур учетных записей

<table><thead><tr><th width="145">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>user_id</code> - Уникальный идентификатор пользователя<br>- <code>company_label</code> - Название компании, связанной с пользователем<br>- <code>first_name</code> - Имя пользователя<br>- <code>last_name</code> - Фамилия пользователя<br>- <code>middle_name</code> - Отчество пользователя<br>- <code>locale</code> - Языковые настройки пользователя<br>- <code>timezone_label</code> - Часовой пояс в формате IANA<br>- <code>master_id</code> - Идентификатор основного пользователя (если текущий является подчиненным)<br>- <code>registration_datetime</code> - Дата регистрации в системе<br>- <code>birth_date</code> - Дата рождения пользователя</td></tr><tr><td><strong>Связи</strong></td><td>Родительский пользователь через <code>master_id</code>, связан с <code>employees</code>, <code>departments</code>, <code>places</code>, <code>tasks</code> через <code>user_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Центральная сущность, связывающая организационные данные; <code>master_id</code> позволяет выстраивать иерархию пользователей для многоуровневых структур учетных записей</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>employees</code></strong></summary>

**Описание**: Записи сотрудников и водителей, используемые для представления людей, работающих в организации, включая персональные данные, сведения о правах, назначения по отделам, аппаратные ключи для идентификации iButton/RFID и данные о местоположении с поддержкой геозон

<table><thead><tr><th width="143">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>employee_id</code> - Идентификатор сущности сотрудника<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>department_id</code> - Идентификатор отдела, к которому назначен сотрудник<br>- <code>first_name</code> - Атрибут first_name таблицы employees<br>- <code>last_name</code> - Атрибут last_name таблицы employees<br>- <code>middle_name</code> - Атрибут middle_name таблицы employees<br>- <code>driver_license_number</code> - Номер водительского удостоверения<br>- <code>driver_license_categories</code> - Категории водительского удостоверения<br>- <code>driver_license_issue_date</code> - Дата выдачи водительского удостоверения<br>- <code>driver_license_valid_till</code> - Дата окончания действия водительского удостоверения<br>- <code>hardware_key</code> - Аппаратный ключ<br>- <code>email</code> - Электронная почта сотрудника<br>- <code>phone_number</code> - Телефон сотрудника без знака "+"<br>- <code>address</code> - Адрес местоположения<br>- <code>personnel_number</code> - Табельный номер сотрудника/водителя<br>- <code>citizen_id_number</code> - Номер социального страхования<br>- <code>latitude</code> - Местоположение, связанное с этим сотрудником<br>- <code>longitude</code> - Местоположение, связанное с этим сотрудником<br>- <code>radius</code> - Местоположение, связанное с этим сотрудником, в метрах<br>- <code>fuel_consumption</code> - Атрибут fuel_consumption таблицы employees<br>- <code>fuel_cost</code> - Атрибут fuel_cost таблицы employees<br>- <code>is_deleted</code> - Атрибут is_deleted таблицы employees</td></tr><tr><td><strong>Связи</strong></td><td>Связи с <code>users</code>, <code>departments</code>, <code>objects</code> (назначенный трекер), отслеживается в <code>driver_history</code> : Изучите исходные схемы ( <code>checkins</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Аппаратный ключ позволяет идентифицировать водителя через iButton или RFID; поддерживает геозоны с <code>latitude</code>, <code>longitude</code>, <code>radius</code> полями</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>departments</code></strong></summary>

**Описание**: Организационные единицы с данными географического местоположения (широта, долгота, радиус), позволяющие выполнять аналитику на основе геозон для отчетности по отделам и привязки сотрудников к местоположению

<table><thead><tr><th width="156">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>department_id</code> - Идентификатор сущности отдела<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>department_label</code> - Атрибут department_label таблицы departments<br>- <code>latitude</code> - Местоположение, связанное с этим отделом<br>- <code>longitude</code> - Местоположение, связанное с этим отделом<br>- <code>radius</code> - Размер геолокации в метрах<br>- <code>address</code> - Атрибут address таблицы departments</td></tr><tr><td><strong>Связи</strong></td><td>Связывает сотрудников с организационной структурой через <code>department_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Поля местоположения поддерживают аналитику на основе геозон для отчетности по отделам</td></tr></tbody></table>

</details>

Отслеживание и мониторинг

<details>

<summary><strong><code>devices</code></strong></summary>

**Описание**: Реестр физических устройств слежения с аппаратными идентификаторами (IMEI), данными SIM-карты, статусом сетевого подключения (уровень сигнала, роуминг, оператор) и назначениями в списке статусов для управления жизненным циклом устройства

<table><thead><tr><th width="138">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>device_id</code> - Идентификатор устройства<br>- <code>owner_id</code> - Идентификатор владельца устройства, в учетной записи которого был добавлен маяк<br>- <code>device_imei</code> - IMEI устройства<br>- <code>phone</code> - Номер SIM-карты устройства<br>- <code>status_listing_id</code> - Идентификатор статуса устройства<br>- <code>network_label</code> - Название сети, к которой подключена SIM-карта<br>- <code>signal_level</code> - Уровень сигнала устройства<br>- <code>has_roaming</code> - Признак доступности роуминга<br>- <code>is_sim_blocked</code> - Признак блокировки SIM-карты<br>- <code>created_at</code> - Дата и время создания записи</td></tr><tr><td><strong>Связи</strong></td><td>Основная сущность, связывающая с <code>objects</code>, <code>models</code>, <code>sensor_description</code>, <code>counters</code>; <code>owner_id</code> references <code>users.user_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Все телематические данные в <code>raw_telematics_data</code> схеме ссылаются на эту таблицу через <code>device_id</code></td></tr></tbody></table>

</details>

<details>

<summary><strong><code>objects</code></strong></summary>

**Описание**: Центральный реестр отслеживаемых сущностей (транспорт, активы, персонал), связывающий физические устройства с организационной структурой через client\_id и group\_id, представляющий «отслеживаемую единицу» с одним активным объектом на устройство

<table><thead><tr><th width="148">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>client_id</code> - Идентификатор сущности клиента<br>- <code>device_id</code> - Идентификатор сущности устройства<br>- <code>object_label</code> - Название объекта<br>- <code>model</code> - Модель устройства<br>- <code>group_id</code> - Идентификатор группы сущности<br>- <code>create_datetime</code> - Дата и время создания новой строки на сервере<br>- <code>is_deleted</code> - Атрибут is_deleted таблицы objects<br>- <code>is_clone</code> - Признак клона</td></tr><tr><td><strong>Связи</strong></td><td>Центральный узел, связывающий устройства с пользователями (<code>client_id</code>), сведениями о транспортных средствах, историей отслеживания, задачами и правилами</td></tr><tr><td><strong>Особые примечания</strong></td><td>Представляет в системе «отслеживаемую единицу»; один объект на одно устройство, находящееся в активном использовании</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>models</code></strong></summary>

**Описание**: Центральный реестр отслеживаемых сущностей (транспорт, активы, персонал), связывающий физические устройства с организационной структурой через client\_id и group\_id, представляющий «отслеживаемую единицу» с одним активным объектом на устройство

<table><thead><tr><th width="135">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>model_id</code> - Идентификатор модели сущности<br>- <code>model</code> - Атрибут model таблицы models<br>- <code>vendor</code> - Название компании, выпустившей трекер<br>- <code>alternative_label</code> - Атрибут alternative_label таблицы models<br>- <code>analog_amount</code> - Количество аналоговых входов трекера<br>- <code>digital_amount</code> - Количество дискретных входов трекера<br>- <code>outputs_amount</code> - Количество дискретных выходов трекера<br>- <code>has_battery_level</code> - Определяет, передает ли трекер показания заряда батареи<br>- <code>has_altitude</code> - Определяет, передает ли трекер высоту<br>- <code>has_phone</code> - Есть ли SIM-карта?<br>- <code>has_gsm_level</code> - Может ли трекер передавать уровень GSM-сигнала?<br>- <code>has_gsm_name</code> - Может ли трекер передавать название GSM-сети или код оператора (MCC + MNC)?<br>- <code>has_gsm_roaming</code> - Может ли трекер передавать статус роуминга?<br>- <code>has_detach_button</code> - Есть ли у трекера датчик отсоединения?<br>- <code>type_output_control</code> - Профиль управления выходами трекера<br>- <code>type_special_control</code> - Содержит специализированные настройки и функциональные модули для отдельных моделей устройств, например режим опасного вождения (hbm_telfm) для оборудования Teltonika<br>- <code>is_clone</code> - Является ли модель клоном другой модели?</td></tr><tr><td><strong>Содержимое</strong></td><td>Флаги функциональных возможностей Boolean указывают, какие поля данных доступны для данного типа устройства</td></tr><tr><td><strong>Особые примечания</strong></td><td>Используйте флаги функциональных возможностей, чтобы определить допустимые датчики и входы при запросе телематических данных</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>sensor_description</code></strong></summary>

**Описание**: Полная конфигурация датчиков, связывающая входы устройства с бизнес-логикой, включая сопоставление входов, единицы измерения, коэффициенты преобразования (multiplier/divider), таблицы калибровки для датчиков топлива, пороги точности и логику группировки для агрегированных показаний датчиков

<table><thead><tr><th width="142">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>sensor_id</code> - Идентификатор сущности датчика<br>- <code>device_id</code> - Идентификатор сущности устройства<br>- <code>sensor_label</code> - Название датчика для интерфейса<br>- <code>input_label</code> - Название поля сообщения (атрибута), из которого берутся данные датчика. Если равно "input_status", это дискретный датчик<br>- <code>sensor_type</code> - Тип датчика<br>- <code>units_type</code> - Единицы измерения<br>- <code>multiplier</code> - Множитель — число, на которое умножается значение поля. Только для измерительных датчиков<br>- <code>divider</code> - Делитель — число, на которое делится значение поля. Только для измерительных датчиков<br>- <code>accuracy</code> - Заданное процентное значение для расчета абсолютной погрешности объема бака. Эта погрешность используется для определения момента заправки или слива. Применяется только для датчиков топлива<br>- <code>calibration_data</code> - Атрибут calibration_data таблицы sensor_description<br>- <code>input_id</code> - Номер входа для дискретного датчика<br>- <code>group_id</code> - Датчики одного типа с одинаковыми group_id и source_id считаются относящимися к одной группе. Их данные суммируются или усредняются в зависимости от значения group_type. Это требуется для агрегированных датчиков. Используется в измерительных датчиках<br>- <code>group_type</code> - 0 - суммировать значения датчиков внутри группы, 1 - усреднять<br>- <code>sensor_units</code> - Название единицы, введенное пользователем, если units_type=0 (custom)<br>- <code>parameters</code> - Необязательный объект с дополнительными параметрами parent_ids - необязательный массив parent_ids для составного датчика. volume - double. Необязательно. Объем для составного датчика. parent_ids - необязательно. Массив int. Массив parent_ids для составного датчика. volume - необязательно. Double. Объем для составного датчика. min - необязательно. Double. Минимально допустимое сырое значение для датчика. max - необязательно. Double. Максимально допустимое сырое значение для датчика. max_lowering_by_time - необязательно. Double. Максимально допустимое снижение значения в час. max_lowering_by_mileage - необязательно. Double. Максимально допустимое снижение значения на 100 км. ignore_drains_in_move - необязательно. Boolean. По умолчанию false. Если true, сливы топлива не будут определяться во время движения. ignore_refuels_in_move - необязательно. Boolean. По умолчанию false. Если true, заправки не будут определяться во время движения. refuel_gap_minutes - необязательно. Integer. По умолчанию 5. Время в минутах после начала движения, когда заправки будут определяться во время движения. custom_field_name - необязательно. Boolean. По умолчанию false. Параметр определяет, является ли поле input_name пользовательским значением, введенным пользователем. Это имеет смысл только если модель трекера поддерживает feature has_custom_fields</td></tr><tr><td><strong>Связи</strong></td><td>Связывает входы устройства (из <code>raw_telematics_data.inputs</code>) с бизнес-логикой через <code>device_id</code> : Изучите исходные схемы ( <code>input_label</code> сопоставление</td></tr><tr><td><strong>Особые примечания</strong></td><td><code>calibration_data</code> (JSONB) хранит таблицы калибровки, специфичные для датчиков уровня топлива; <code>multiplier</code> : Изучите исходные схемы ( <code>divider</code> преобразует сырые значения в единицы</td></tr></tbody></table>

</details>

Управление активами

<details>

<summary><strong><code>vehicles</code></strong></summary>

**Описание**: Полный реестр транспортных средств, содержащий характеристики (габариты, масса, грузоподъемность), документацию (VIN, регистрация, страховка), эксплуатационные параметры (расход топлива, объем бака) и текущее назначение трекера через object\_id для управления автопарком и контроля соответствия требованиям

<table><thead><tr><th width="144">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>vehicle_id</code> - Идентификатор сущности транспортного средства<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>garage_id</code> - Идентификатор сущности гаража<br>- <code>vehicle_label</code> - Атрибут vehicle_label таблицы vehicles<br>- <code>registration_number</code> - Регистрационный номер/номерной знак транспортного средства<br>- <code>vin</code> - Атрибут vin таблицы vehicles<br>- <code>manufacture_year</code> - Атрибут manufacture_year таблицы vehicles<br>- <code>fuel_type</code> - Атрибут fuel_type таблицы vehicles<br>- <code>fuel_cost</code> - Атрибут fuel_cost таблицы vehicles<br>- <code>fuel_tank_volume</code> - Атрибут fuel_tank_volume таблицы vehicles<br>- <code>max_speed</code> - Атрибут max_speed таблицы vehicles<br>- <code>model</code> - Атрибут model таблицы vehicles<br>- <code>color</code> - Атрибут color таблицы vehicles<br>- <code>trailer</code> - Атрибут trailer таблицы vehicles<br>- <code>additional_info</code> - Атрибут additional_info таблицы vehicles<br>- <code>vehicle_type</code> - Атрибут vehicle_type таблицы vehicles<br>- <code>vehicle_subtype</code> - Атрибут vehicle_subtype таблицы vehicles<br>- <code>vehicle_status_id</code> - Идентификатор статуса транспортного средства<br>- <code>chassis_number</code> - Атрибут chassis_number таблицы vehicles<br>- <code>frame_number</code> - Атрибут frame_number таблицы vehicles<br>- <code>trailer_reg_number</code> - Атрибут trailer_reg_number таблицы vehicles<br>- <code>payload_weight</code> - Атрибут payload_weight таблицы vehicles<br>- <code>payload_height</code> - Атрибут payload_height таблицы vehicles<br>- <code>payload_length</code> - Атрибут payload_length таблицы vehicles<br>- <code>payload_width</code> - Атрибут payload_width таблицы vehicles<br>- <code>passenger_capacity</code> - Максимальное количество пассажиров<br>- <code>gross_weight</code> - Атрибут gross_weight таблицы vehicles<br>- <code>standard_fuel_consumption</code> - Нормальный средний расход топлива в литрах на 100 км<br>- <code>fuel_grade</code> - Атрибут fuel_grade таблицы vehicles<br>- <code>wheel_arrangement</code> - Атрибут wheel_arrangement таблицы vehicles<br>- <code>tyre_size</code> - Размер транспортного средства: габариты и размер колес<br>- <code>tyres_number</code> - Количество колес<br>- <code>liability_insurance_policy_number</code> - Атрибут liability_insurance_policy_number таблицы vehicles<br>- <code>liability_insurance_valid_till</code> - Дата окончания действия страхования гражданской ответственности<br>- <code>free_insurance_policy_number</code> - Атрибут free_insurance_policy_number таблицы vehicles<br>- <code>free_insurance_valid_till_date</code> - Дата окончания действия бесплатной страховки</td></tr><tr><td><strong>Связи</strong></td><td>Связи с <code>objects</code> (текущий трекер), <code>garages</code> (место обслуживания), <code>vehicle_service_tasks</code>; отслеживается в <code>vehicle_trackers_history</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Поля физических размеров (<code>payload_length</code>, <code>payload_width</code>, <code>payload_height</code>, <code>gross_weight</code>) поддерживают аналитику планирования загрузки; даты страховки обеспечивают контроль соответствия требованиям</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>garages</code></strong></summary>

**Описание**: Места расположения сервисных и ремонтных объектов с географическими координатами (широта, долгота, радиус), контактной информацией для механиков и диспетчеров, позволяющие обнаруживать визиты в сервис на основе геозон и выполнять анализ близости

<table><thead><tr><th width="135">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>garage_id</code> - Идентификатор сущности гаража<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>latitude</code> - Объект местоположения<br>- <code>longitude</code> - Объект местоположения<br>- <code>radius</code> - Размер геолокации в метрах<br>- <code>address</code> - Объект местоположения<br>- <code>organization_label</code> - Идентификатор депо<br>- <code>mechanic_name</code> - Имя механика<br>- <code>dispatcher_name</code> - Имя диспетчера</td></tr><tr><td><strong>Связи</strong></td><td>На него ссылается <code>vehicles.garage_id</code> для назначения места обслуживания</td></tr><tr><td><strong>Особые примечания</strong></td><td>Поля местоположения позволяют выполнять обнаружение визитов в сервис на основе геозон и анализ близости</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>vehicle_service_tasks</code></strong></summary>

**Описание**: Отслеживание графика обслуживания и истории сервисных работ с несколькими типами триггеров (по дате, по пробегу, по моточасам), повторяющимися интервалами задач, многоканальными уведомлениями (email, SMS, push) и различием между плановыми (is\_repeat) и внеплановыми событиями обслуживания

<table><thead><tr><th width="132">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>service_task_id</code> - Идентификатор сущности сервисной задачи<br>- <code>vehicle_id</code> - Идентификатор сущности транспортного средства<br>- <code>description</code> - Атрибут description таблицы vehicle_service_tasks<br>- <code>status</code> - Значение статуса атрибута status<br>- <code>cost</code> - Атрибут cost таблицы vehicle_service_tasks<br>- <code>start_date</code> - Дата и время, связанная с атрибутом start_date<br>- <code>end_date</code> - Дата и время, связанная с атрибутом end_date<br>- <code>completion_date</code> - Дата и время, связанная с атрибутом completion_date<br>- <code>predicted_datetime</code> - Дата и время, связанная с атрибутом predicted_datetime<br>- <code>mileage_limit</code> - Атрибут mileage_limit таблицы vehicle_service_tasks<br>- <code>engine_hours_limit</code> - Атрибут engine_hours_limit таблицы vehicle_service_tasks<br>- <code>start_mileage</code> - Атрибут start_mileage таблицы vehicle_service_tasks<br>- <code>start_engine_hours</code> - Атрибут start_engine_hours таблицы vehicle_service_tasks<br>- <code>mileage_notification_interval</code> - Атрибут mileage_notification_interval таблицы vehicle_service_tasks<br>- <code>engine_hours_notification_interval</code> - Атрибут engine_hours_notification_interval таблицы vehicle_service_tasks<br>- <code>date_notification_interval</code> - Преобразование целого числа N в N дней<br>- <code>mileage_repeat_interval</code> - Атрибут mileage_repeat_interval таблицы vehicle_service_tasks<br>- <code>engine_hours_repeat_interval</code> - Атрибут engine_hours_repeat_interval таблицы vehicle_service_tasks<br>- <code>date_repeat_interval</code> - Преобразование целого числа N в N дней<br>- <code>notification_emails</code> - Атрибут notification_emails таблицы vehicle_service_tasks<br>- <code>notification_sms_phone_numbers</code> - Атрибут notification_sms_phone_numbers таблицы vehicle_service_tasks<br>- <code>is_notification_push_enabled</code> - Атрибут is_notification_push_enabled таблицы vehicle_service_tasks<br>- <code>completion_mileage</code> - Атрибут completion_mileage таблицы vehicle_service_tasks<br>- <code>completion_engine_hours</code> - Атрибут completion_engine_hours таблицы vehicle_service_tasks<br>- <code>is_repeat</code> - Атрибут is_repeat таблицы vehicle_service_tasks<br>- <code>is_unplanned</code> - Атрибут is_unplanned таблицы vehicle_service_tasks<br>- <code>comment</code> - Атрибут comment таблицы vehicle_service_tasks</td></tr><tr><td><strong>Содержимое</strong></td><td>Поддерживает три типа триггеров: по дате, по пробегу, по моточасам; настройки уведомлений для email, SMS, push</td></tr><tr><td><strong>Особые примечания</strong></td><td><code>is_repeat</code> и поля интервалов позволяют настраивать повторяющиеся графики обслуживания; <code>is_unplanned</code> различает плановое и реактивное обслуживание</td></tr></tbody></table>

</details>

Местоположение и маршрутизация

<details>

<summary><strong><code>zones</code></strong></summary>

**Описание**: Области геозон с виртуальными периметрами, определяемыми с помощью кругов или полигонов для отслеживания событий въезда и выезда транспортных средств/активов, поддерживающие автоматизацию на основе правил и аналитику местоположений с цветовой кодировкой для визуального различия

<table><thead><tr><th width="150">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>zone_id</code> - Идентификатор сущности зоны<br>- <code>client_id</code> - Идентификатор сущности клиента<br>- <code>zone_label</code> - Атрибут zone_label таблицы zones<br>- <code>zone_type</code> - Атрибут zone_type таблицы zones<br>- <code>latitude</code> - Необязательный объект, ограничивающая рамка, которая может полностью содержать возвращаемый результат<br>- <code>longitude</code> - Необязательный объект, ограничивающая рамка, которая может полностью содержать возвращаемый результат<br>- <code>circle_center_latitude</code> - Атрибут circle_center_latitude таблицы zones<br>- <code>circle_center_longitude</code> - Атрибут circle_center_longitude таблицы zones<br>- <code>radius</code> - Размер геолокации в метрах<br>- <code>address</code> - Атрибут address таблицы zones<br>- <code>color</code> - Атрибут color таблицы zones</td></tr><tr><td><strong>Содержимое</strong></td><td>Типы зон включают circle, polygon (определяемый через <code>geofence_points</code>), а также специальные классификации областей</td></tr><tr><td><strong>Связи</strong></td><td>На него ссылается <code>rules2zones</code>, <code>users2zones</code>; вершины полигона хранятся в <code>geofence_points</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Функции PostGIS можно использовать для проверки попадания точки в полигон при сложном анализе геозон</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>places</code></strong></summary>

**Описание**: Точки интереса с географическими координатами, определением радиуса и расширяемой поддержкой пользовательских полей для хранения контактной информации клиентов и данных, специфичных для бизнеса, что позволяет интеграцию с CRM/ERP через external\_id и отчетность на основе местоположения

<table><thead><tr><th width="129">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>place_id</code> - Идентификатор сущности места<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>place_label</code> - Атрибут place_label таблицы places<br>- <code>latitude</code> - Объект местоположения<br>- <code>longitude</code> - Объект местоположения<br>- <code>radius</code> - Размер геолокации в метрах<br>- <code>address</code> - Атрибут address таблицы places<br>- <code>description</code> - Атрибут description таблицы places<br>- <code>external_id</code> - Идентификатор для интеграции с внешними системами (CRM)<br>- <code>custom_fields</code> - Дополнительные поля<br>- <code>assigned_datetime</code> - Дата и время назначения точки интереса пользователю</td></tr><tr><td><strong>Связи</strong></td><td>Расширено значениями пользовательских полей через <code>places_text_fields</code>, <code>places_decimal_fields</code>, <code>places_bigint_fields</code>, <code>places_longtext_fields</code>, <code>places_linked_entity_fields</code></td></tr><tr><td><strong>Особые примечания</strong></td><td><code>custom_fields</code> JSONB обеспечивает быстрый доступ; связанные таблицы позволяют фильтрацию и сортировку по пользовательским атрибутам</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>geofence_points</code></strong></summary>

**Описание**: Упорядоченные координаты вершин (числовое поле определяет последовательность), задающие границы полигона для сложных геозон, обеспечивая точные географические периметры за пределами простых круговых зон, используются с PostGIS ST\_MakePolygon для геометрических операций

<table><thead><tr><th width="133">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>zone_id</code> - ID зоны, к которой прикреплена эта форма<br>- <code>number</code> - Серийный номер<br>- <code>latitude</code> - Местоположение<br>- <code>longitude</code> - Местоположение</td></tr><tr><td><strong>Связи</strong></td><td>Несколько записей на <code>zone_id</code> задают границы полигона; <code>number</code> поле определяет порядок вершин</td></tr><tr><td><strong>Особые примечания</strong></td><td>Запрос с <code>ORDER BY number</code> для восстановления пути полигона; используйте с PostGIS ST_MakePolygon для геометрических операций</td></tr></tbody></table>

</details>

Управление задачами и рабочими процессами

<details>

<summary><strong><code>tasks</code></strong></summary>

**Описание**: Назначения нарядов на работы с проверкой местоположения (широта, долгота, радиус), временными окнами (time\_from, time\_to), требованиями к длительности визита (stay\_duration\_minutes, arrival\_duration\_minutes), иерархической структурой через parent\_task\_id и отслеживанием статусов для управления полевым сервисом и доставкой

<table><thead><tr><th width="130">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>task_id</code> - Идентификатор сущности задачи<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>parent_task_id</code> - Идентификатор родительской сущности задачи<br>- <code>task_label</code> - Атрибут task_label таблицы tasks<br>- <code>status</code> - Значение статуса атрибута status<br>- <code>task_type</code> - Тип задачи, задача, маршрут или контрольная точка<br>- <code>latitude</code> - Атрибут широты таблицы tasks<br>- <code>longitude</code> - Атрибут долготы таблицы tasks<br>- <code>radius</code> - Размер геолокации в метрах<br>- <code>arrival_datetime</code> - Когда трекер прибывает в зону задачи. ИГНОРИРУЕТСЯ при создании/обновлении<br>- <code>created_at</code> - Атрибут created_at таблицы tasks<br>- <code>status_change_datetime</code> - Дата и время обновления задачи<br>- <code>time_from</code> - Дата и время, связанная с атрибутом time_from<br>- <code>time_to</code> - Дата и время, связанная с атрибутом time_to<br>- <code>stay_duration</code> - Атрибут stay_duration таблицы tasks<br>- <code>stay_duration_minutes</code> - Продолжительность визита. Время, которое мобильный сотрудник должен провести на месте назначения, чтобы успешно завершить задачу. Несколько визитов суммируются<br>- <code>arrival_duration_minutes</code> - Игнорировать случайные визиты короче указанной длительности. При расчёте минимальной длительности визиты короче указанной длительности будут игнорироваться<br>- <code>max_delay_minuts</code> - Допустимая задержка. Максимальное время, на которое сотрудник может опоздать. Любая задача, выполненная в течение этого времени, будет помечена как "late"<br>- <code>is_stay_control_enabled</code> - Атрибут is_stay_control_enabled таблицы tasks<br>- <code>address</code> - Атрибут address таблицы tasks<br>- <code>description</code> - Атрибут description таблицы tasks<br>- <code>custom_fields</code> - Атрибут custom_fields таблицы tasks<br>- <code>external_id</code> - Идентификатор внешней сущности<br>- <code>order_sort</code> - Атрибут order_sort таблицы tasks<br>- <code>created_by</code> - Источник созданной задачи</td></tr><tr><td><strong>Содержимое</strong></td><td>Поддерживает иерархические задачи через <code>parent_task_id</code>; временные окна, определяемые <code>time_from</code>/<code>time_to</code>; проверку геозоны по местоположению и радиусу</td></tr><tr><td><strong>Связи</strong></td><td>Связи с <code>forms</code> (сбор данных), <code>task_history</code> (изменения статуса), <code>objects</code> (назначенный трекер)</td></tr><tr><td><strong>Особые примечания</strong></td><td><code>stay_duration</code> : Изучите исходные схемы ( <code>arrival_duration_minutes</code> обеспечивают контроль соответствия для задач доставки и обслуживания</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>forms</code></strong></summary>

**Описание**: Настраиваемые формы сбора данных для фиксации структурированной информации при выполнении задачи или отметке в мобильном приложении, с полями и значениями, хранящимися в JSON, опциональной проверкой местоположения (is\_submission\_in\_zone) и обязательными требованиями к отправке при привязке к задачам

<table><thead><tr><th width="141">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>form_id</code> - Идентификатор сущности формы<br>- <code>task_id</code> - ID задачи, к которой прикреплена эта форма<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>form_label</code> - Пользовательский ярлык формы<br>- <code>полями</code> - Если true, форму можно отправить только в зоне задачи<br>- <code>values</code> - Словарь с ID полей в качестве ключей и объектами field_value в качестве значений. Ключ используется для связывания поля и соответствующего ему значения<br>- <code>submitted_at</code> - Дата последней отправки значений формы<br>- <code>submission_latitude</code> - Местоположение, с которого в последний раз были отправлены значения формы<br>- <code>submission_longitude</code> - Местоположение, с которого в последний раз были отправлены значения формы<br>- <code>submission_address</code> - Местоположение, с которого в последний раз были отправлены значения формы<br>- <code>is_submission_in_zone</code> - Если true, форму можно отправить только в зоне задачи<br>- <code>description</code> - Дата создания этой формы (или привязки к задаче)<br>- <code>created_at</code> - Дата создания этой формы (или привязки к задаче)</td></tr><tr><td><strong>Содержимое</strong></td><td><code>полями</code> определяет структуру формы (JSON); <code>values</code> содержит отправленные данные (JSON)</td></tr><tr><td><strong>Связи</strong></td><td>Связи с <code>tasks</code> (связанное наряд-заказ), <code>objects</code> (отправитель), упоминается в <code>checkins</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Флаг проверки местоположения <code>is_submission_in_zone</code> обеспечивает правила отправки формы на основе геозоны</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>checkins</code></strong></summary>

**Описание**: Записи о посещаемости и активности, основанные на местоположении, отправляемые через мобильное приложение, с отслеживанием планового и фактического времени прибытия (planned\_datetime vs actual\_datetime) с географическими координатами и измерениями точности местоположения (radius) для отчётности по пунктуальности

<table><thead><tr><th width="129">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>checkin_id</code> - Идентификатор сущности checkin<br>- <code>employee_id</code> - Идентификатор сущности сотрудника также является идентификатором для водителей<br>- <code>object_id</code> - Устройство сотрудника<br>- <code>form_id</code> - Идентификатор сущности формы<br>- <code>user_id</code> - Пользователь-сотрудник<br>- <code>planned_datetime</code> - Время устройства, когда была выполнена отметка<br>- <code>actual_datetime</code> - Время сервера, когда запрос/сообщение было обработано<br>- <code>latitude</code> - Местоположение, с которого были отправлены отметки<br>- <code>longitude</code> - Местоположение, с которого были отправлены отметки<br>- <code>radius</code> - Погрешность позиционирования в точке, в метрах<br>- <code>address</code> - Адрес отметки<br>- <code>comment</code> - Атрибут comment таблицы checkins</td></tr><tr><td><strong>Связи</strong></td><td>Связывает сотрудников с формами и местоположениями; отслеживает отклонение от планового графика</td></tr><tr><td><strong>Особые примечания</strong></td><td>Временное отклонение между <code>planned_datetime</code> : Изучите исходные схемы ( <code>actual_datetime</code> обеспечивает отчётность по пунктуальности; radius определяет допустимый допуск по местоположению</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>task_history</code></strong></summary>

**Описание**: Полный журнал аудита событий жизненного цикла задачи, фиксирующий все изменения статуса, назначения, обновления и модификации полей с временными метками (event\_datetime), привязкой к пользователю и типами активности (create, update, assign, status\_change), хранящимися в поле payload для анализа соответствия и рабочих процессов

<table><thead><tr><th width="137">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>task_history_id</code> - Идентификатор сущности истории задачи<br>- <code>task_id</code> - Идентификатор сущности задачи<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>activity</code> - Выполненная операция. Может быть "create", "update", "assign" или "status_change"<br>- <code>event_datetime</code> - Дата и время события<br>- <code>payload</code> - Зависит от операции. Обычно содержит поля, которые были изменены во время операции</td></tr><tr><td><strong>Содержимое</strong></td><td>Типы активности, определённые в <code>description_parameters</code>; <code>payload</code> хранит детали события (текст)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Необходимо для анализа выполнения задач, отчётности по переходам статусов и отслеживания активности пользователей</td></tr></tbody></table>

</details>

Правила и автоматизация

<details>

<summary><strong><code>rules</code></strong></summary>

**Описание**: Правила обнаружения событий с настраиваемыми условиями срабатывания (превышение скорости, нарушения геозоны, пороговые значения датчиков, время простоя), хранящимися в параметрах (JSONB), и настройками многоканальных уведомлений (alert\_email, alert\_sms, alert\_phone, is\_push\_enabled) для автоматического мониторинга и оповещения на основе данных устройства и сервера

<table><thead><tr><th width="131">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>rule_id</code> - Идентификатор сущности правила<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>client_id</code> - Идентификатор сущности клиента<br>- <code>event_type</code> - Атрибут event_type таблицы rules<br>- <code>event_label</code> - Атрибут event_label таблицы rules<br>- <code>event_group</code> - Атрибут event_group таблицы rules<br>- <code>description</code> - Атрибут description таблицы rules<br>- <code>parameters</code> - Параметры события. Для получения подробной информации о доступных параметрах см. <a href="https://www.navixy.com/docs/navixy-api/user-api/backend-api/resources/tracking/tracker/rules/rule_types/">Navixy API docs</a>.<br>- <code>alert_email</code> - Почта для уведомлений<br>- <code>alert_sms</code> - Номера телефонов для SMS-уведомлений<br>- <code>alert_phone</code> - Телефоны для голосовых вызовов<br>- <code>is_push_enabled</code> - Если true, push-уведомления доступны<br>- <code>created_at</code> - Атрибут created_at таблицы rules<br>- <code>is_deleted</code> - Атрибут is_deleted таблицы rules<br>- <code>maximum</code> - Ограничения, применяемые к различным правилам. Например, для правила времени простоя при работающем двигателе в минутах<br>- <code>event_comment1</code> - Атрибут event_comment1 таблицы rules<br>- <code>event_comment2</code> - Атрибут event_comment2 таблицы rules</td></tr><tr><td><strong>Содержимое</strong></td><td>Параметры правила (JSONB) определяют условия срабатывания; поддерживаются уведомления по электронной почте, SMS, телефону и push-уведомления</td></tr><tr><td><strong>Связи</strong></td><td>Связи с объектами через <code>rules2objects</code>, с зонами через <code>rules2zones</code></td></tr><tr><td><strong>Особые примечания</strong></td><td><code>event_type</code> определяет конкретный сценарий мониторинга (превышение скорости, нарушение геозоны, порог датчика); <code>maximum</code> поле позволяет агрегировать события для оповещения по порогам</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>rules2objects</code></strong></summary>

**Описание**: Связь многие-ко-многим, связывающая правила с отслеживаемыми объектами с индивидуальной настройкой параметров для каждого объекта через object\_params (JSONB), что позволяет задавать разные пороговые значения (например, ограничения скорости) для каждого транспортного средства или актива в рамках одного правила

<table><thead><tr><th width="140">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>rule_id</code> - Идентификатор сущности правила<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>param_group_number</code> - Атрибут param_group_number таблицы rules2objects<br>- <code>object_params</code> - Атрибут object_params таблицы rules2objects</td></tr><tr><td><strong>Содержимое</strong></td><td><code>object_params</code> (JSONB) позволяет настраивать правило для каждого объекта (например, разные ограничения скорости для каждого транспортного средства)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Связь многие-ко-многим позволяет одному правилу контролировать несколько объектов с разными параметрами</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>rules2zones</code></strong></summary>

**Описание**: Связь многие-ко-многим, связывающая правила с геозонами, позволяющая одному правилу отслеживать события входа/выхода в нескольких географических областях для сложных сценариев пространственного мониторинга

<table><thead><tr><th width="144">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>rule_id</code> - Идентификатор сущности правила<br>- <code>zone_id</code> - Идентификатор сущности зоны</td></tr><tr><td><strong>Особые примечания</strong></td><td>Связь многие-ко-многим позволяет осуществлять много-зонный мониторинг для одного правила (например, оповещение при входе в любую из нескольких запрещённых зон)</td></tr></tbody></table>

</details>

Статусы и категоризация

<details>

<summary><strong><code>statuses</code></strong></summary>

**Описание**: Пользовательские определения статусов в списках статусов, включая свойства отображения (color для отображения на сайте, order\_sort для позиционирования), используемые для представления рабочих состояний устройства или сотрудника с поддержкой мягкого удаления через флаг is\_deleted

<table><thead><tr><th width="128">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>status_id</code> - Идентификатор сущности статуса<br>- <code>listing_id</code> - Идентификатор сущности списка<br>- <code>status_label</code> - Значение статуса атрибута status_label<br>- <code>color</code> - Цвет, используемый для отображения на сайте<br>- <code>order_sort</code> - Позиция сортировки внутри списка статусов<br>- <code>is_deleted</code> - Атрибут is_deleted таблицы statuses</td></tr><tr><td><strong>Связи</strong></td><td>Группы статусов, организованные по <code>listing_id</code> (ссылается на <code>status_listings</code>); используется в <code>status_history</code></td></tr><tr><td><strong>Особые примечания</strong></td><td><code>order_sort</code> определяет последовательность отображения; цвет обеспечивает визуальное различие в отчётности</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>status_listings</code></strong></summary>

**Описание**: Определения наборов статусов, управляющие тем, какие значения статусов доступны для устройств или сотрудников, с флагами прав (is\_supervisor\_controlled, is\_employee\_controlled), определяющими, могут ли изменять статусы руководители, сотрудники или оба

<table><thead><tr><th width="144">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>status_listing_id</code> - Идентификатор сущности списка статусов<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>status_listing_label</code> - Значение статуса атрибута status_listing_label<br>- <code>is_supervisor_controlled</code> - Если true, руководители могут изменять рабочий статус, например, используя мобильное приложение мониторинга<br>- <code>is_employee_controlled</code> - Если true, сотрудники могут изменять свой рабочий статус самостоятельно, например, используя мобильное приложение трекинга<br>- <code>is_deleted</code> - Атрибут is_deleted таблицы status_listings</td></tr><tr><td><strong>Связи</strong></td><td>На него ссылается <code>devices.status_listing_id</code> : Изучите исходные схемы ( <code>statuses.listing_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Флаги управления определяют, кто может менять статусы: только руководитель, самообслуживание сотрудника или оба</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>status_history</code></strong></summary>

**Описание**: Журнал аудита всех переходов статусов устройства с временными метками (changed\_datetime на устройстве, server\_datetime на сервере), привязкой к пользователю (updated\_by) и фиксацией местоположения (latitude, longitude, address), позволяющий проводить географический анализ изменений статуса и отчётность по местоположению начала/окончания рабочего дня

<table><thead><tr><th width="143">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>status_history_id</code> - Идентификатор сущности истории статусов<br>- <code>device_id</code> - Идентификатор сущности устройства<br>- <code>old_status_id</code> - Идентификатор сущности старого статуса<br>- <code>new_status_id</code> - Идентификатор сущности нового статуса<br>- <code>updated_by</code> - Дата и время, связанные с атрибутом updated_by<br>- <code>changed_datetime</code> - Дата и время назначения нового статуса на устройстве<br>- <code>server_datetime</code> - Дата и время назначения нового статуса на сервере<br>- <code>latitude</code> - Определение местоположения устройств во время изменения статуса<br>- <code>longitude</code> - Определение местоположения устройств во время изменения статуса<br>- <code>address</code> - Определение местоположения устройств во время изменения статуса</td></tr><tr><td><strong>Связи</strong></td><td>Связи с <code>devices</code>, <code>statuses</code> (старый и новый), <code>description_parameters</code> (для <code>updated_by</code> роли)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Фиксация местоположения позволяет проводить географический анализ переходов статусов; полезно для отчётности по местоположению начала/окончания рабочего дня</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>tags</code></strong></summary>

**Описание**: Пользовательские метки категоризации с цветовым кодированием, позволяющие быстро фильтровать и искать по нескольким типам сущностей (места, геозоны, сотрудники, задачи, трекеры, транспортные средства) для гибкой организации

<table><thead><tr><th width="149">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>tag_id</code> - ID сущности тега<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>tag_label</code> - Атрибут tag_label таблицы tags<br>- <code>color</code> - Атрибут color таблицы tags</td></tr><tr><td><strong>Связи</strong></td><td>Применяются к сущностям через <code>tag_links</code>; область применения определяется пользователем</td></tr><tr><td><strong>Особые примечания</strong></td><td>Гибкая система категоризации, поддерживающая несколько тегов на одну сущность</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>tag_links</code></strong></summary>

**Описание**: Таблица полиморфной связи, связывающая теги с любым типом сущности через entity\_type и entity\_id, с полем ordinal для управления порядком отображения, обеспечивающая гибкую маркировку множества сущностей

<table><thead><tr><th width="127">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>tag_id</code> - ID сущности тега<br>- <code>entity_type</code> - Атрибут entity_type таблицы tag_links<br>- <code>entity_id</code> - Идентификатор сущности<br>- <code>ordinal</code> - Атрибут ordinal таблицы tag_links</td></tr><tr><td><strong>Содержимое</strong></td><td><code>entity_type</code> идентифицирует таблицу (vehicle, employee, task и т. д.); <code>ordinal</code> определяет порядок отображения</td></tr><tr><td><strong>Особые примечания</strong></td><td>Полиморфная связь позволяет применять теги к разным типам сущностей</td></tr></tbody></table>

</details>

Группы и иерархия

<details>

<summary><strong><code>groups</code></strong></summary>

**Описание**: Структура организационного группирования для трекеров, обеспечивающая визуальную организацию в пользовательском интерфейсе с настраиваемыми цветами (group\_color) и иерархическим управлением в стиле папок, в настоящее время выполняет только визуальную функцию

<table><thead><tr><th width="148">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>group_id</code> - Группа трекеров (связанная через objects.group_id). Разделение на группы можно увидеть, например, в списке маяков<br>- <code>client_id</code> - Идентификатор сущности клиента<br>- <code>group_label</code> - Задаваемое пользователем название группы, от 1 до 60 печатных символов, например "Сотрудники"<br>- <code>group_color</code> - Цвет группы в веб-формате (без #), например "FF6DDC". Определяет цвет маркеров трекеров на карте</td></tr><tr><td><strong>Связи</strong></td><td>На него ссылается <code>objects.group_id</code>; принадлежность клиента через <code>client_id</code> (ссылается на <code>users</code>)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Обеспечивает организацию отслеживаемых сущностей в виде папок для отчётности и прав доступа</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>groups_objects</code></strong></summary>

**Описание**: Связь многие-ко-многим между группами и объектами с использованием составного первичного ключа (groups\_client\_id, objects\_client\_id), позволяющая объектам одновременно принадлежать нескольким группам для гибких организационных структур

<table><thead><tr><th width="135">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>groups_client_id</code> - Идентификатор сущности клиента для групп<br>- <code>objects_client_id</code> - Идентификатор сущности клиента для объектов</td></tr><tr><td><strong>Особые примечания</strong></td><td>Позволяет объектам одновременно принадлежать нескольким группам; запрос с обоими <code>client_id</code> значениями для членства в группе</td></tr></tbody></table>

</details>

Пользовательские поля и сущности

<details>

<summary><strong><code>entities</code></strong></summary>

**Описание**: Реестр типов сущностей, определяющий, какие бизнес-сущности поддерживают пользовательские поля и какова структура их полей (sections, field\_order), хранящаяся в entity\_label (JSONB), что позволяет динамически расширять схему для мест, задач и других сущностей без изменений базы данных

<table><thead><tr><th width="141">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>entity_id</code> - Идентификатор сущности<br>- <code>user_id</code> - Идентификатор сущности пользователя<br>- <code>entity_label</code> - id - int. Идентификатор сущности. type - enum. В настоящее время поддерживается только "place". layout - object описывает структуру полей для сущности. sections - array of objects. Каждый раздел может содержать одно или несколько полей. В layout должен существовать как минимум один раздел. label - string. Название раздела. field_order - string array. Встроенные поля и ID пользовательских полей (в виде строк)<br>- <code>builtin_type</code> - Атрибут builtin_type таблицы entities</td></tr><tr><td><strong>Связи</strong></td><td>На него ссылается <code>custom_fields</code> для определения, какие пользовательские поля применяются к каким типам сущностей</td></tr><tr><td><strong>Особые примечания</strong></td><td><code>builtin_type</code> ссылается на <code>description_parameters</code> для системно определённых классификаций сущностей</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>custom_fields</code></strong></summary>

**Описание**: Определения пользовательских полей, обеспечивающие динамическое расширение схемы для типов сущностей, с настраиваемыми типами полей (custom\_field\_type), правилами проверки и параметрами в parameters (JSONB) и флагами обязательности (is\_required) для гибкого сбора данных по местам, задачам и другим сущностям

<table><thead><tr><th width="146">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>custom_field_id</code> - Идентификатор сущности пользовательского поля<br>- <code>entity_id</code> - Идентификатор сущности<br>- <code>custom_field_label</code> - Название поля<br>- <code>custom_field_type</code> - Тип данных в поле<br>- <code>description</code> - Описание поля<br>- <code>is_required</code> - Обязательное или нет?<br>- <code>parameters</code> - Параметры поля</td></tr><tr><td><strong>Содержимое</strong></td><td><code>parameters</code> (JSONB) хранит конфигурацию, специфичную для типа поля (правила проверки, параметры выпадающего списка и т. д.)</td></tr><tr><td><strong>Связи</strong></td><td>Определяет доступные пользовательские атрибуты для сущностей; тип поля связан с <code>description_parameters</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Обеспечивает динамическое расширение схемы без изменений базы данных; широко используется в <code>places</code> : Изучите исходные схемы ( <code>tasks</code></td></tr></tbody></table>

</details>

Историческое отслеживание

<details>

<summary><strong><code>driver_history</code></strong></summary>

**Описание**: Полный журнал аудита назначений сотрудников на транспортные средства во времени, отслеживающий переходы от old\_employee\_id к new\_employee\_id с временными метками (changed\_datetime, server\_datetime), данными о местоположении (latitude, longitude, address), информацией о аппаратном ключе и привязкой к пользователю (updated\_by), что позволяет выполнять аналитику по водителям при смене автомобилей

<table><thead><tr><th width="146">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>driver_history_id</code> - Идентификатор сущности истории водителя<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>old_employee_id</code> - Идентификатор сущности старого сотрудника<br>- <code>new_employee_id</code> - Идентификатор сущности нового сотрудника<br>- <code>hardware_key</code> - Атрибут hardware_key таблицы driver_history<br>- <code>changed_datetime</code> - Дата и время изменений, внесённых на устройство<br>- <code>server_datetime</code> - Дата и время изменений, внесённых на сервере<br>- <code>updated_by</code> - Дата и время, связанные с атрибутом updated_by<br>- <code>latitude</code> - Атрибут latitude таблицы driver_history<br>- <code>longitude</code> - Атрибут longitude таблицы driver_history<br>- <code>address</code> - Атрибут address таблицы driver_history</td></tr><tr><td><strong>Связи</strong></td><td>Отслеживает назначение водителей на транспортные средства во времени; связывается с <code>employees</code> : Изучите исходные схемы ( <code>objects</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Необходимо для отчётности по водителям при смене автомобилей; фиксация местоположения позволяет анализировать места изменения назначения</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>vehicle_trackers_history</code></strong></summary>

**Описание**: Журнал аудита, отслеживающий, какие GPS-устройства (object\_id) были установлены в каких транспортных средствах (vehicle\_id) во времени, с временными метками изменений (changed\_datetime), обеспечивая точную историческую атрибуцию данных и расчёт пробега при перемещении трекеров между транспортными средствами

<table><thead><tr><th width="144">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>vehicle_tracker_history_id</code> - Идентификатор сущности истории трекера транспортного средства<br>- <code>vehicle_id</code> - Идентификатор сущности транспортного средства<br>- <code>object_id</code> - Объект идентификатора сущности<br>- <code>changed_datetime</code> - Дата и время, связанные с атрибутом changed_datetime</td></tr><tr><td><strong>Связи</strong></td><td>Отслеживает, какое GPS-устройство было установлено в каком транспортном средстве во времени</td></tr><tr><td><strong>Особые примечания</strong></td><td>Критически важно для анализа исторических данных при перемещении трекеров между транспортными средствами; обеспечивает точную атрибуцию пробега и использования</td></tr></tbody></table>

</details>

Справочные и поисковые данные

<details>

<summary><strong><code>description_parameters</code></strong></summary>

**Описание**: Справочные данные на уровне системы, предоставляющие понятные для человека метки (description) для перечислимых целочисленных значений (key), используемых по всей базе данных, организованные по полю type (например, task\_status, fuel\_type, counter\_type, entity\_classification) для согласованного преобразования значений в отчётности и интерфейсе

<table><thead><tr><th width="146">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>key</code> - Возможное значение в атрибуте<br>- <code>type</code> - Составной атрибут, состоящий из имени таблицы, за которым следует подчёркивание и имя атрибута в таблице<br>- <code>description</code> - Неявное значение атрибута</td></tr><tr><td><strong>Содержимое</strong></td><td>Предоставляет человекочитаемые метки для кодированных значений по всей базе данных (статус задачи, типы топлива, типы счётчиков и т. д.)</td></tr><tr><td><strong>Связи</strong></td><td>Ссылается через внешние ключи из нескольких таблиц для стандартизированной категоризации</td></tr><tr><td><strong>Особые примечания</strong></td><td>Необходимо для преобразования целочисленных кодов в читаемые значения в отчётности; <code>type</code> связанные перечисления групп полей</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>counters</code></strong></summary>

**Описание**: Конфигурации одометра и счётчика моточасов, связывающие показания датчиков устройства (sensor\_id) с измерениями расстояния или времени с коэффициентами умножения для преобразования единиц (km, miles, hours) и counter\_type из description\_parameters, определяющими тип измерения

<table><thead><tr><th width="140">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>counter_id</code> - Внутренний ID<br>- <code>device_id</code> - Идентификатор сущности устройства<br>- <code>counter_type</code> - Тип счётчика<br>- <code>sensor_id</code> - Идентификатор сущности датчика<br>- <code>multiplier</code> - Коэффициент для преобразования значений в одну из метрик (km, l и т. д.)</td></tr><tr><td><strong>Связи</strong></td><td>Связывает устройства с показаниями датчиков, которые представляют счётчики расстояния или времени</td></tr><tr><td><strong>Особые примечания</strong></td><td><code>multiplier</code> преобразует импульсы датчика в фактические единицы (km, miles, hours); <code>counter_type</code> из <code>description_parameters</code> определяет тип измерения</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>device_output_name</code></strong></summary>

**Описание**: Пользовательские метки для каналов выхода устройства, сопоставляющие числовые идентификаторы выходов (number) с заданными пользователем именами (label), такими как "Door Lock" или "Engine Block", для понятной отчётности и анализа команд и состояний выходов устройства

<table><thead><tr><th width="140">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>device_id</code> - Идентификатор сущности устройства<br>- <code>number</code> - Атрибут number таблицы device_output_name<br>- <code>label</code> - Атрибут label таблицы device_output_name</td></tr><tr><td><strong>Содержимое</strong></td><td>Сопоставляет номера каналов выхода с заданными пользователем именами (например, "Door Lock", "Engine Block")</td></tr><tr><td><strong>Особые примечания</strong></td><td>Обеспечивает читаемую отчётность при анализе команд и состояний выходов устройства</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>device_settings</code></strong></summary>

**Описание**: Пары ключ-значение конфигурации устройства, синхронизированные с исходной платформы. Каждая строка хранит один параметр конфигурации для конкретного устройства.

<table><thead><tr><th width="140">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>device_id</code> - Идентификатор сущности устройства<br>- <code>key</code> - Имя параметра<br>- <code>value</code> - Значение параметра</td></tr><tr><td><strong>Первичный ключ</strong></td><td>Составной ключ: <code>(device_id, key)</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Заполняется во время полной синхронизации клиента. Используйте эту таблицу для чтения значений конфигурации уровня устройства вместе с телематическими или бизнес-данными.</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>event_description</code></strong></summary>

**Описание**: Справочная таблица кодов событий трекера с понятными описаниями. Содержит 134 записи, охватывающие распространённые события трекера, такие как SOS, спящий режим, зажигание и изменения цифровых входов/выходов.

<table><thead><tr><th width="140">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td>- <code>event_id</code> - Код события (первичный ключ)<br>- <code>description</code> - Человекочитаемое название события</td></tr><tr><td><strong>Особые примечания</strong></td><td>Свяжите с <code>raw_telematics_data.tracking_data_core</code> по <code>event_id</code> для отображения названий событий в отчётах и панелях вместо числовых кодов.</td></tr></tbody></table>

</details>

## `raw_telematics_data` структура

Узел **`raw_telematics_data`** схема содержит три основных типа таблиц, которые совместно обеспечивают полные данные об устройстве.

<figure><img src="/files/4c08e8dbd0576e03876c62139e271799b1c81d2e" alt="Bronze layer raw telematics data ERD"><figcaption><p>ERD сырых телематических данных слоя Bronze</p></figcaption></figure>

{% hint style="info" %}
Интерактивная диаграмма схемы raw\_telematics\_data доступна на **dbdiagram.io**: <https://dbdiagram.io/d/v1-schema-telematics-bd-67a0acef263d6cf9a0d8e750>
{% endhint %}

Ниже приведены сведения о схеме сырых телематических данных.

{% code title="схема raw\_telematics\_data" expandable="true" %}

```sql
Таблица tracking_data_core {

  device_id integer [primary key]

  device_time timestampz [primary key]

  platform_time timestampz

  record_added_at timestampz [default: `now()`]

  latitude integer

  longitude integer

  speed integer

  altitude integer

  satellites integer

  event_id integer

  gps_fix_type integer

  hdop integer

  

  indexes {(device_id, device_time)}

}

  

Таблица inputs {

  event_id integer [primary key]

  device_id integer [primary key]

  record_added_at timestampz [default: `now()`]

  device_time timestampz [primary key]

  sensor_name text [primary key]

  value text

  indexes {(device_id, device_time)}

}

  

Таблица states {

  event_id integer [primary key]

  device_id serial [primary key]

  record_added_at timestampz [default: `now()`]

  device_time timestampz [primary key]

  state_name text [primary key]

  value text

  indexes {(device_id, device_time)}

}

  

Ref: inputs.(device_id, device_time) > tracking_data_core.(device_id, device_time)

Ref: states.(device_id, device_time) > tracking_data_core.(device_id, device_time)
```

{% endcode %}

### Ключевые таблицы по категориям

Каждая таблица служит определённой цели в сборе различных аспектов информации об устройстве:

<details>

<summary><code>tracking_data_core</code></summary>

**Назначение**: Основные данные о местоположении и движении

<table><thead><tr><th width="181.20001220703125">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>device_id</code>, <code>device_time</code>, <code>platform_time</code>, <code>latitude</code>, <code>longitude</code>, <code>speed</code>, <code>altitude</code>, <code>satellites</code>, <code>hdop</code>, <code>event_id</code></td></tr><tr><td><strong>Индексирование</strong></td><td>Оптимизировано с индексом по (<code>device_id</code>, <code>device_time</code>)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Данные о местоположении (широта и долгота) используют целочисленный формат с точностью 10⁷ для оптимальной производительности TimescaleDB<br><br>Скорость также хранится в целых числах, поэтому её нужно делить на 100</td></tr></tbody></table>

</details>

<details>

<summary><code>inputs</code></summary>

**Назначение**: Показания датчиков с устройств

<table><thead><tr><th width="182">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>input_id</code>, <code>device_id</code>, <code>device_time</code>, <code>sensor_name</code>, <code>value</code></td></tr><tr><td><strong>Содержимое</strong></td><td>Аналоговые показания (уровень топлива, температура, напряжение), вычисленные значения (обороты двигателя)</td></tr><tr><td><strong>Связи</strong></td><td><pre data-overflow="wrap"><code>FROM raw_telematics_data.inputs AS i
JOIN raw_business_data.sensor_description AS sd
    ON i.device_id = sd.device_id AND i.sensor_name = sd.input_label
JOIN raw_telematics_data.tacking_data_core AS tdc
    ON i.device_id = tdc.device_id AND i.device_time = tdc.device_time
</code></pre></td></tr></tbody></table>

</details>

<details>

<summary><code>states</code></summary>

**Назначение**: Индикаторы статуса устройства и режимы работы

<table><thead><tr><th width="174.800048828125">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>state_id</code>, <code>device_id</code>, <code>device_time</code>, <code>state_name</code>, <code>value</code></td></tr><tr><td><strong>Содержимое</strong></td><td>Индикаторы режима работы (работает, простой, выключен), состояния компонентов (зажигание, двери)</td></tr><tr><td><strong>Формат значения</strong></td><td>Булевы значения (1/0) или определённые коды состояния</td></tr></tbody></table>

</details>

Данные в этой схеме поступают напрямую с устройств с минимальной задержкой (обычно в пределах секунд). Схема оптимизирована для временных рядов с использованием TimescaleDB для эффективного хранения и извлечения.

## Дополнительная информация

### Проверка данных

База данных обеспечивает целостность данных с помощью нескольких механизмов:

* **Ограничения CHECK** проверяют, что значения находятся в допустимых диапазонах
* **Внешние ключи** обеспечивают согласованность связей между таблицами
* **Ограничения NOT NULL** гарантируют, что обязательные поля всегда содержат значения
* **Значения DEFAULT** предоставляют значение по умолчанию, если данные явно не указаны

### Оптимизация запросов

Таблицы организованы с использованием определённых стратегий индексирования:

* Все таблицы включают **индексы по времени** по `record_added_at`
* Столбцы внешних ключей имеют выделенные индексы для повышения производительности соединений
* Часто используемые комбинации столбцов имеют **составные индексы**
* TimescaleDB предоставляет специализированные индексы для запросов к временным рядам

## `repo` структура данных

{% hint style="warning" %}
**В настоящее время эта схема находится в разработке.** Если вас интересует ранний доступ или у вас есть вопросы по этой функциональности, пожалуйста, свяжитесь с <iotquery@navixy.com>.
{% endhint %}

Узел `repo` схема предоставляет комплексную основу для управления организационными структурами, активами, устройствами и их взаимосвязями в многопользовательских средах. Построенная на PostgreSQL 14+ с расширением ltree, схема поддерживает иерархические организации, определение пользовательских полей для любого типа сущности, разграничение доступа на основе ролей с ограничениями на уровне объектов и полный аудит изменений с отслеживанием изменений на уровне полей. Все сущности могут быть расширены без изменения схемы, локализованы для международных внедрений и связаны через гибкие полиморфные отношения.

Схема решает сложные сценарии управления данными, включая иерархии активов автопарка на разных организационных уровнях, многопользовательские SaaS-платформы, требующие изоляции данных, операции, регулируемые требованиями соответствия с детализированным аудитом, и системы, которым нужны динамические модели данных, адаптируемые с помощью пользовательских полей, а не миграций базы данных.

<figure><img src="/files/6ffdd84df61589807fdb4b1419db0eb9e6e66aba" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Интерактивная диаграмма`repo` схемы данных доступна на **dbdiagram.io**: <https://dbdiagram.io/d/Navixy-Repo-data-schema-68ad788c1e7a611967a0930e>
{% endhint %}

Найдите `repo` схемы ниже.

{% code title="схема данных repo" expandable="true" %}

```sql
// ============================================
// Новая схема DataHub - Customer Journey
// PostgreSQL 14+ с расширением ltree
// Версия: 2.0 (Концепция)
// ============================================

// ============================================
// БАЗОВЫЕ СПРАВОЧНЫЕ ТАБЛИЦЫ (иерархия ci_base)
// ============================================

Table ci_base {
  id uuid [primary key]
  code text [not null]
  title_en text [not null]
  order int
  is_system boolean [not null, default: false]
  discriminator text [not null]
  catalog_id uuid
  organization_id uuid
  parent_id uuid
  path ltree
  is_hierarchical boolean [default: false]
  extra jsonb
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  deleted_at timestamptz
  
  indexes {
    (parent_id) [name: 'idx_ci_parent']
    (path) [type: gist, name: 'idx_ci_path_gist']
    (catalog_id) [name: 'idx_ci_catalog']
    (organization_id) [name: 'idx_ci_org']
    (discriminator) [name: 'idx_ci_discriminator']
    (code) [unique, name: 'uq_ci_code_per_type']
    (organization_id, code) [unique, name: 'uq_ci_org_code']
  }
}

Table ci_module {
  id uuid [primary key]
}

Table ci_catalog_category {
  id uuid [primary key]
}

Table ci_country {
  id uuid [primary key]
}

Table ci_role {
  id uuid [primary key]
}

Table ci_entity_type {
  id uuid [primary key]
}

Table ci_device_status {
  id uuid [primary key]
}

Table ci_permission_scope {
  id uuid [primary key]
  module_id uuid
  entity_type_id uuid
  category text
}

Table ci_device_type {
  id uuid [primary key]
}

Table ci_asset_type {
  id uuid [primary key]
  category_id uuid
}

Table ci_asset_type_category {
  id uuid [primary key]
}

Table ci_inventory_type {
  id uuid [primary key]
}

Table ci_organization_type {
  id uuid [primary key]
}

Table ci_user_type {
  id uuid [primary key]
}

Table ci_asset_group_type {
  id uuid [primary key]
  max_items int
  color text
  icon text
  allowed_asset_type_id uuid
}

Table ci_device_relation_type {
  id uuid [primary key]
}

Table ci_tag {
  id uuid [primary key]
  entity_type_id uuid
  color text
}

// ============================================
// БАЗОВАЯ СУЩНОСТЬ С ПОДДЕРЖКОЙ ПОЛЬЗОВАТЕЛЬСКИХ ПОЛЕЙ
// ============================================

Table customizable_entity {
  id uuid [primary key]
  entity_type_id uuid [not null]
  cf_data jsonb
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  
  indexes {
    (entity_type_id) [name: 'idx_customizable_entity_type']
  }
}

// ============================================
// ОСНОВНЫЕ БИЗНЕС-СУЩНОСТИ
// ============================================

Table organization {
  id uuid [primary key]
  parent_id uuid
  path ltree
  organization_type_id uuid [not null]
  title_en text [not null]
  is_active boolean [not null, default: true]
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  deleted_at timestamptz
  deleted_by uuid
  
  indexes {
    (parent_id) [name: 'idx_org_parent']
    (path) [type: gist, name: 'idx_org_path_gist']
    (organization_type_id) [name: 'idx_org_type']
  }
}

Table catalog {
  id uuid [primary key]
  organization_id uuid [not null]
  module_id uuid
  category_id uuid
  title_en text [not null]
  is_system boolean [not null, default: false]
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  
  indexes {
    (organization_id) [name: 'idx_catalog_org']
    (module_id) [name: 'idx_catalog_module']
  }
}

Table user {
  id uuid [primary key]
  organization_id uuid [not null]
  user_type_id uuid [not null]
  identity_provider text [not null]
  identity_provider_id uuid [not null]
  full_name text [not null]
  is_active boolean [not null, default: true]
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  deleted_at timestamptz
  deleted_by uuid
  
  indexes {
    (organization_id) [name: 'idx_user_org']
    (user_type_id) [name: 'idx_user_type']
    (organization_id, identity_provider, identity_provider_id) [unique, name: 'uq_user_org_idp']
  }
}

// ============================================
// КОНТРОЛЬ ДОСТУПА (ACL)
// ============================================

Table user_role {
  id uuid [primary key]
  user_id uuid [not null]
  role_id uuid [not null]
  assigned_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  assigned_by uuid
  
  indexes {
    (user_id) [name: 'idx_user_role_user']
    (role_id) [name: 'idx_user_role_role']
    (user_id, role_id) [unique, name: 'uq_user_role']
  }
}

Table acl_role_permission {
  id uuid [primary key]
  role_id uuid [not null]
  permission_scope_id uuid [not null]
  target_entity_id uuid
  actions int [not null]
  granted_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  granted_by uuid
  
  indexes {
    (role_id) [name: 'idx_acl_role_perm_role']
    (permission_scope_id) [name: 'idx_acl_role_perm_scope']
    (role_id, permission_scope_id, target_entity_id) [unique, name: 'uq_acl_role_permission']
  }
}

Table acl_user_scope {
  id uuid [primary key]
  user_id uuid [not null]
  permission_scope_id uuid [not null]
  target_entity_id uuid [not null]
  actions int [not null]
  
  indexes {
    (user_id, permission_scope_id) [name: 'idx_acl_user_scope_user']
    (user_id, permission_scope_id, target_entity_id) [unique, name: 'uq_acl_user_scope']
  }
}

// ============================================
// БИЗНЕС-СУЩНОСТИ
// ============================================

Table asset {
  id uuid [primary key]
  organization_id uuid [not null]
  asset_type_id uuid [not null]
  label text [not null]
  description text
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  deleted_at timestamptz
  deleted_by uuid
  
  indexes {
    (organization_id) [name: 'idx_asset_org']
    (asset_type_id) [name: 'idx_asset_type']
  }
}

Table inventory {
  id uuid [primary key]
  organization_id uuid [not null]
  inventory_type_id uuid [not null]
  code text [not null]
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  deleted_at timestamptz
  deleted_by uuid
  
  indexes {
    (organization_id) [name: 'idx_inventory_org']
    (inventory_type_id) [name: 'idx_inventory_type']
    (organization_id, code) [unique, name: 'uq_inventory_org_code']
  }
}

Table device {
  id uuid [primary key]
  organization_id uuid [not null]
  device_type_id uuid [not null]
  status_id uuid [not null]
  hw_id text
  label text [not null]
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  deleted_at timestamptz
  deleted_by uuid
  
  indexes {
    (organization_id) [name: 'idx_device_org']
    (device_type_id) [name: 'idx_device_type']
    (status_id) [name: 'idx_device_status']
    (hw_id) [name: 'idx_device_hw_id']
  }
}

Table device_asset_link {
  id uuid [primary key]
  device_id uuid [unique, not null]
  asset_id uuid [not null]
  linked_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  linked_by uuid
  
  indexes {
    (device_id) [unique, name: 'idx_device_asset_link_device']
    (asset_id) [name: 'idx_device_asset_link_asset']
  }
}

Table device_inventory_link {
  id uuid [primary key]
  device_id uuid [unique, not null]
  inventory_id uuid [not null]
  linked_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  linked_by uuid
  
  indexes {
    (device_id) [unique, name: 'idx_device_inventory_link_device']
    (inventory_id) [name: 'idx_device_inventory_link_inventory']
  }
}

Table device_relation {
  id uuid [primary key]
  master_id uuid [not null]
  slave_id uuid [not null]
  relation_type_id uuid [not null]
  
  indexes {
    (master_id) [name: 'idx_device_relation_master']
    (slave_id) [name: 'idx_device_relation_slave']
    (master_id, slave_id, relation_type_id) [unique, name: 'uq_device_relation']
  }
}

Table asset_group {
  id uuid [primary key]
  organization_id uuid [not null]
  group_type_id uuid [not null]
  title_en text [not null]
  description text
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  deleted_at timestamptz
  deleted_by uuid
  
  indexes {
    (organization_id) [name: 'idx_asset_group_org']
    (group_type_id) [name: 'idx_asset_group_type']
  }
}

Table asset_group_item {
  id uuid [primary key]
  group_id uuid [not null]
  asset_id uuid [not null]
  attached_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  detached_at timestamptz
  
  indexes {
    (group_id) [name: 'idx_asset_group_item_group']
    (asset_id) [name: 'idx_asset_group_item_asset']
    (group_id, asset_id, detached_at) [unique, name: 'uq_asset_group_item']
  }
}

Table entity_tag {
  id uuid [primary key]
  tag_id uuid [not null]
  entity_id uuid [not null]
  tagged_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  
  indexes {
    (tag_id) [name: 'idx_entity_tag_tag']
    (entity_id) [name: 'idx_entity_tag_entity']
    (tag_id, entity_id) [unique, name: 'uq_entity_tag']
  }
}

// ============================================
// ЛОКАЛИЗАЦИЯ
// ============================================

Table i18n_text {
  entity_id uuid [pk]
  field_code text [pk]
  locale text [pk]
  text_value text [not null]
  
  indexes {
    (entity_id) [name: 'idx_i18n_entity']
    (locale) [name: 'idx_i18n_locale']
  }
}

// ============================================
// ПОЛЬЗОВАТЕЛЬСКИЕ ПОЛЯ - ОПРЕДЕЛЕНИЯ
// ============================================

Table custom_field_def {
  id uuid [primary key]
  organization_id uuid [not null]
  owner_entity_type_id uuid [not null]
  code text [not null]
  title_en text [not null]
  field_type text [not null]
  is_multi boolean [not null, default: false]
  is_required boolean [not null, default: false]
  order int
  ref_entity_type_id uuid
  ref_catalog_id uuid
  created_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  updated_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  
  indexes {
    (organization_id) [name: 'idx_cfd_org']
    (owner_entity_type_id) [name: 'idx_cfd_owner_type']
    (organization_id, owner_entity_type_id, code) [unique, name: 'uq_cfd_org_type_code']
  }
}

// ============================================
// ПОЛЬЗОВАТЕЛЬСКИЕ ПОЛЯ - ЗНАЧЕНИЯ (по типам)
// ============================================

Table custom_field_value_text {
  customizable_entity_id uuid [pk]
  field_def_id uuid [pk]
  value_index smallint [pk]
  value text [not null]
  
  indexes {
    (field_def_id, value) [name: 'idx_cfv_text_value']
  }
}

Table custom_field_value_number {
  customizable_entity_id uuid [pk]
  field_def_id uuid [pk]
  value_index smallint [pk]
  value numeric [not null]
  
  indexes {
    (field_def_id, value) [name: 'idx_cfv_number_value']
  }
}

Table custom_field_value_boolean {
  customizable_entity_id uuid [pk]
  field_def_id uuid [pk]
  value_index smallint [pk]
  value boolean [not null]
  
  indexes {
    (field_def_id, value) [name: 'idx_cfv_boolean_value']
  }
}

Table custom_field_value_date {
  customizable_entity_id uuid [pk]
  field_def_id uuid [pk]
  value_index smallint [pk]
  value date [not null]
  
  indexes {
    (field_def_id, value) [name: 'idx_cfv_date_value']
  }
}

Table custom_field_value_datetime {
  customizable_entity_id uuid [pk]
  field_def_id uuid [pk]
  value_index smallint [pk]
  value timestamptz [not null]
  
  indexes {
    (field_def_id, value) [name: 'idx_cfv_datetime_value']
  }
}

Table custom_field_value_entity {
  customizable_entity_id uuid [pk]
  field_def_id uuid [pk]
  value_index smallint [pk]
  ref_entity_id uuid [not null]
  
  indexes {
    (field_def_id, ref_entity_id) [name: 'idx_cfv_entity_value']
  }
}

Table custom_field_value_catalog {
  customizable_entity_id uuid [pk]
  field_def_id uuid [pk]
  value_index smallint [pk]
  ref_item_id uuid [not null]
  
  indexes {
    (field_def_id, ref_item_id) [name: 'idx_cfv_catalog_value']
  }
}

// ============================================
// АУДИТ
// ============================================

Table audit_event {
  id uuid [primary key]
  event_category text [not null]
  user_id uuid
  identity_provider_id uuid
  ip_address inet
  user_agent text
  aggregate_type text
  aggregate_id uuid
  event_type text [not null]
  event_data jsonb
  occurred_at timestamptz [not null, default: `CURRENT_TIMESTAMP`]
  
  indexes {
    (user_id, occurred_at) [name: 'idx_audit_event_user']
    (aggregate_type, aggregate_id, occurred_at) [name: 'idx_audit_event_aggregate']
    (event_category, occurred_at) [name: 'idx_audit_event_category']
    (event_type, occurred_at) [name: 'idx_audit_event_type']
  }
}

// ============================================
// СВЯЗИ
// ============================================

Ref: ci_base.catalog_id > catalog.id
Ref: ci_base.organization_id > organization.id
Ref: ci_base.parent_id > ci_base.id

Ref: ci_module.id - ci_base.id
Ref: ci_catalog_category.id - ci_base.id
Ref: ci_country.id - ci_base.id
Ref: ci_role.id - ci_base.id
Ref: ci_entity_type.id - ci_base.id
Ref: ci_device_status.id - ci_base.id
Ref: ci_permission_scope.id - ci_base.id
Ref: ci_device_type.id - ci_entity_type.id
Ref: ci_asset_type.id - ci_entity_type.id
Ref: ci_asset_type_category.id - ci_base.id
Ref: ci_inventory_type.id - ci_entity_type.id
Ref: ci_organization_type.id - ci_entity_type.id
Ref: ci_user_type.id - ci_entity_type.id
Ref: ci_asset_group_type.id - ci_entity_type.id
Ref: ci_device_relation_type.id - ci_base.id
Ref: ci_tag.id - ci_base.id

Ref: ci_permission_scope.module_id > ci_module.id
Ref: ci_permission_scope.entity_type_id > ci_entity_type.id
Ref: ci_asset_type.category_id > ci_asset_type_category.id
Ref: ci_asset_group_type.allowed_asset_type_id > ci_asset_type.id
Ref: ci_tag.entity_type_id > ci_entity_type.id

Ref: customizable_entity.entity_type_id > ci_entity_type.id

Ref: organization.id - customizable_entity.id
Ref: organization.parent_id > organization.id
Ref: organization.organization_type_id > ci_organization_type.id
Ref: organization.deleted_by > user.id

Ref: catalog.organization_id > organization.id
Ref: catalog.module_id > ci_module.id
Ref: catalog.category_id > ci_catalog_category.id

Ref: user.id - customizable_entity.id
Ref: user.organization_id > organization.id
Ref: user.user_type_id > ci_user_type.id
Ref: user.deleted_by > user.id

Ref: user_role.user_id > user.id
Ref: user_role.role_id > ci_role.id
Ref: user_role.assigned_by > user.id

Ref: acl_role_permission.role_id > ci_role.id
Ref: acl_role_permission.permission_scope_id > ci_permission_scope.id
Ref: acl_role_permission.granted_by > user.id

Ref: acl_user_scope.user_id > user.id
Ref: acl_user_scope.permission_scope_id > ci_permission_scope.id

Ref: asset.id - customizable_entity.id
Ref: asset.organization_id > organization.id
Ref: asset.asset_type_id > ci_asset_type.id
Ref: asset.deleted_by > user.id

Ref: inventory.id - customizable_entity.id
Ref: inventory.organization_id > organization.id
Ref: inventory.inventory_type_id > ci_inventory_type.id
Ref: inventory.deleted_by > user.id

Ref: device.id - customizable_entity.id
Ref: device.organization_id > organization.id
Ref: device.device_type_id > ci_device_type.id
Ref: device.status_id > ci_device_status.id
Ref: device.deleted_by > user.id

Ref: device_asset_link.device_id - device.id
Ref: device_asset_link.asset_id > asset.id
Ref: device_asset_link.linked_by > user.id

Ref: device_inventory_link.device_id - device.id
Ref: device_inventory_link.inventory_id > inventory.id
Ref: device_inventory_link.linked_by > user.id

Ref: device_relation.master_id > device.id
Ref: device_relation.slave_id > device.id
Ref: device_relation.relation_type_id > ci_device_relation_type.id

Ref: asset_group.id - customizable_entity.id
Ref: asset_group.organization_id > organization.id
Ref: asset_group.group_type_id > ci_asset_group_type.id
Ref: asset_group.deleted_by > user.id

Ref: asset_group_item.group_id > asset_group.id
Ref: asset_group_item.asset_id > asset.id

Ref: entity_tag.tag_id > ci_tag.id

Ref: custom_field_def.organization_id > organization.id
Ref: custom_field_def.owner_entity_type_id > ci_entity_type.id
Ref: custom_field_def.ref_entity_type_id > ci_entity_type.id
Ref: custom_field_def.ref_catalog_id > catalog.id

Ref: custom_field_value_text.customizable_entity_id > customizable_entity.id
Ref: custom_field_value_text.field_def_id > custom_field_def.id

Ref: custom_field_value_number.customizable_entity_id > customizable_entity.id
Ref: custom_field_value_number.field_def_id > custom_field_def.id

Ref: custom_field_value_boolean.customizable_entity_id > customizable_entity.id
Ref: custom_field_value_boolean.field_def_id > custom_field_def.id

Ref: custom_field_value_date.customizable_entity_id > customizable_entity.id
Ref: custom_field_value_date.field_def_id > custom_field_def.id

Ref: custom_field_value_datetime.customizable_entity_id > customizable_entity.id
Ref: custom_field_value_datetime.field_def_id > custom_field_def.id

Ref: custom_field_value_entity.customizable_entity_id > customizable_entity.id
Ref: custom_field_value_entity.field_def_id > custom_field_def.id
Ref: custom_field_value_entity.ref_entity_id > customizable_entity.id

Ref: custom_field_value_catalog.customizable_entity_id > customizable_entity.id
Ref: custom_field_value_catalog.field_def_id > custom_field_def.id
Ref: custom_field_value_catalog.ref_item_id > ci_base.id

Ref: audit_event.user_id > user.id
```

{% endcode %}

### Частота обновления

Данные в `repo` схеме синхронизируются в реальном времени с исходными системами. Обновления происходят немедленно по мере возникновения изменений, а аудит хранит все модификации для обеспечения соответствия требованиям и исторического анализа.

### `ci_base`

Узел `repo` схема использует шаблон Single Table Inheritance для всех справочных данных через `ci_base` таблицу:

Узел `repo` схема использует **Single Table Inheritance** шаблон для всех справочных данных через `ci_base` таблицу. Такой дизайн объединяет системные словари, классификации и пользовательские справочные элементы в единую структуру, обеспечивая согласованность и гибкость во всей схеме.

**Архитектура:**

Узел `ci_base` таблица служит основой для всех справочных данных, используя поле `discriminator` для идентификации конкретного типа справочника. Каждый тип справочника имеет соответствующую таблицу (например, `ci_device_type`, `ci_asset_type`), которая использует тот же `id` что и `ci_base`, создавая типобезопасную наследуемую связь.

**Как бизнес-сущности подключаются к ci\_base:**

Все бизнес-сущности в `repo` схеме ссылаются на `ci_base` подтипы для определения своей классификации и поведения:

* `organization` → ссылается на `ci_organization_type` (которая наследуется от `ci_entity_type` → `ci_base`)
* `user` → ссылается на `ci_user_type` (которая наследуется от `ci_entity_type` → `ci_base`)
* `device` → ссылается на `ci_device_type` : Изучите исходные схемы ( `ci_device_status` (обе наследуются от `ci_base`)
* `asset` → ссылается на `ci_asset_type` (которая наследуется от `ci_entity_type` → `ci_base`)
* `inventory` → ссылается на `ci_inventory_type` (которая наследуется от `ci_entity_type` → `ci_base`)
* `asset_group` → ссылается на `ci_asset_group_type` (которая наследуется от `ci_entity_type` → `ci_base`)

**Категории типов справочников:**

| Категория                       | Таблицы                                                                                                                                 | Назначение                                                                                                        |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **Системная конфигурация**      | `ci_module`, `ci_country`, `ci_role`                                                                                                    | Определяют системные модули, географические справочники и пользовательские роли                                   |
| **Определения типов сущностей** | `ci_entity_type`, `ci_device_type`, `ci_asset_type`, `ci_inventory_type`, `ci_organization_type`, `ci_user_type`, `ci_asset_group_type` | Классифицируют все бизнес-сущности по типу                                                                        |
| **Статус и классификация**      | `ci_device_status`, `ci_asset_type_category`                                                                                            | Отслеживают состояния сущностей и группируют типы в категории                                                     |
| **Контроль доступа**            | `ci_permission_scope`                                                                                                                   | Определяет, какие разрешения могут быть выданы (связан с `ci_module` : Изучите исходные схемы ( `ci_entity_type`) |
| **Связи**                       | `ci_device_relation_type`                                                                                                               | Определяет типы отношений между устройствами (master-slave, backup и т. д.)                                       |
| **Категоризация**               | `ci_tag`, `ci_catalog_category`                                                                                                         | Обеспечивает гибкую организацию тегов и каталога                                                                  |

<details>

<summary><strong>Примеры шаблонов запросов</strong></summary>

```sql
-- Получить все типы устройств для организации (системные + пользовательские)
SELECT cb.id, cb.code, cb.title_en, cb.is_system
FROM repo.ci_base cb
JOIN repo.ci_device_type dt ON dt.id = cb.id
WHERE cb.discriminator = 'device_type'
  AND (cb.is_system = true OR cb.organization_id = $org_id)
  AND cb.deleted_at IS NULL;

-- Получить тип объекта с его категорией
SELECT 
  cb.code as asset_type_code,
  cb.title_en as asset_type_name,
  cat_cb.title_en as category_name
FROM repo.ci_base cb
JOIN repo.ci_asset_type at ON at.id = cb.id
LEFT JOIN repo.ci_asset_type_category cat ON cat.id = at.category_id
LEFT JOIN repo.ci_base cat_cb ON cat_cb.id = cat.id
WHERE cb.discriminator = 'asset_type'
  AND cb.deleted_at IS NULL;

-- Получить иерархическую структуру тегов
SELECT cb.id, cb.code, cb.title_en, cb.path, cb.parent_id
FROM repo.ci_base cb
JOIN repo.ci_tag t ON t.id = cb.id
WHERE cb.discriminator = 'tag'
  AND cb.deleted_at IS NULL
ORDER BY cb.path;
```

</details>

### Ключевые таблицы по категориям

Таблицы в `repo` схемы организованы в функциональные категории. Ниже приведены краткие описания наиболее важных таблиц по их бизнес-назначению.

<details>

<summary><code>organization</code></summary>

**Назначение:** Управление иерархией организаций

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>parent_id</code>, <code>path</code>, <code>organization_type_id</code>, <code>title_en</code>, <code>is_active</code>, <code>deleted_at</code></td></tr><tr><td><strong>Индексирование</strong></td><td>Индекс GiST по <code>path</code> для иерархических запросов, индексы по <code>parent_id</code> : Изучите исходные схемы ( <code>organization_type_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Использует ltree для многоуровневых иерархий, наследуется от <code>customizable_entity</code> для поддержки пользовательских полей</td></tr></tbody></table>

</details>

<details>

<summary><code>user</code></summary>

**Назначение:** Учётные записи пользователей и аутентификация

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>organization_id</code>, <code>user_type_id</code>, <code>identity_provider</code>, <code>identity_provider_id</code>, <code>full_name</code>, <code>is_active</code></td></tr><tr><td><strong>Индексирование</strong></td><td>Уникальный индекс по (<code>organization_id</code>, <code>identity_provider</code>, <code>identity_provider_id</code>)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Интеграция с внешним провайдером идентификации (Keycloak, Auth0, Okta), наследуется от <code>customizable_entity</code></td></tr></tbody></table>

</details>

<details>

<summary><code>device</code></summary>

**Назначение:** Физические устройства отслеживания

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>organization_id</code>, <code>device_type_id</code>, <code>status_id</code>, <code>hw_id</code>, <code>label</code></td></tr><tr><td><strong>Индексирование</strong></td><td>Индексы по <code>organization_id</code>, <code>device_type_id</code>, <code>status_id</code>, <code>hw_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Аппаратный идентификатор для отслеживания устройства, наследуется от <code>customizable_entity</code> для пользовательских полей</td></tr></tbody></table>

</details>

<details>

<summary><code>asset</code></summary>

**Назначение:** Физические или виртуальные объекты

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>organization_id</code>, <code>asset_type_id</code>, <code>label</code>, <code>description</code></td></tr><tr><td><strong>Индексирование</strong></td><td>Индексы по <code>organization_id</code> : Изучите исходные схемы ( <code>asset_type_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Наследуется от <code>customizable_entity</code>, связаны с устройствами через <code>device_asset_link</code></td></tr></tbody></table>

</details>

<details>

<summary><code>inventory</code></summary>

**Назначение:** Записи инвентаря и склада

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>organization_id</code>, <code>inventory_type_id</code>, <code>code</code></td></tr><tr><td><strong>Индексирование</strong></td><td>Уникальный индекс по (<code>organization_id</code>, <code>code</code>)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Уникальные коды в рамках организации, связаны с устройствами через <code>device_inventory_link</code></td></tr></tbody></table>

</details>

<details>

<summary><code>asset_group</code></summary>

**Назначение:** Группировка объектов с историческим отслеживанием

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>organization_id</code>, <code>group_type_id</code>, <code>title_en</code>, <code>description</code></td></tr><tr><td><strong>Связи</strong></td><td><code>FROM repo.asset_group AS ag JOIN repo.asset_group_item AS agi ON agi.group_id = ag.id JOIN repo.asset AS a ON a.id = agi.asset_id WHERE agi.detached_at IS NULL</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Членство по времени через <code>asset_group_item</code>, получить текущих участников с помощью <code>WHERE detached_at IS NULL</code></td></tr></tbody></table>

</details>

<details>

<summary><code>custom_field_def</code></summary>

**Назначение:** Определения и метаданные пользовательских полей

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>organization_id</code>, <code>owner_entity_type_id</code>, <code>code</code>, <code>field_type</code>, <code>is_multi</code>, <code>is_required</code></td></tr><tr><td><strong>Содержимое</strong></td><td>Типы полей включают text, number, boolean, date, datetime, entity_ref, catalog_item_ref</td></tr><tr><td><strong>Особые примечания</strong></td><td>Обеспечивает гибкие пользовательские поля для любого типа сущности, значения хранятся в специализированных по типу <code>custom_field_value_*</code> таблицах</td></tr></tbody></table>

</details>

<details>

<summary><code>acl_role_permission</code></summary>

**Назначение:** Управление разрешениями на основе ролей

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>role_id</code>, <code>permission_scope_id</code>, <code>target_entity_id</code>, <code>actions</code></td></tr><tr><td><strong>Содержимое</strong></td><td>Битовая маска действий (READ=1, UPDATE=2, DELETE=4, CREATE=8), разрешения, специфичные для цели или для всего типа сущности</td></tr><tr><td><strong>Связи</strong></td><td><code>FROM repo.user_role AS ur JOIN repo.acl_role_permission AS rp ON rp.role_id = ur.role_id WHERE ur.user_id = $user_id</code></td></tr><tr><td><strong>Особые примечания</strong></td><td>Работает с <code>user_role</code> : Изучите исходные схемы ( <code>acl_user_scope</code> для определения итоговых разрешений пользователя</td></tr></tbody></table>

</details>

<details>

<summary><code>audit_event</code></summary>

**Назначение:** Единый журнал аудита всех системных изменений

<table><thead><tr><th width="139">Атрибут</th><th>Подробности</th></tr></thead><tbody><tr><td><strong>Ключевые поля</strong></td><td><code>id</code>, <code>event_category</code>, <code>user_id</code>, <code>aggregate_type</code>, <code>aggregate_id</code>, <code>event_type</code>, <code>event_data</code>, <code>occurred_at</code></td></tr><tr><td><strong>Индексирование</strong></td><td>Индексы по (<code>user_id</code>, <code>occurred_at</code>), (<code>aggregate_type</code>, <code>aggregate_id</code>, <code>occurred_at</code>), (<code>event_category</code>, <code>occurred_at</code>)</td></tr><tr><td><strong>Особые примечания</strong></td><td>Разделено по <code>occurred_at</code> (ежемесячно), две категории: <code>auth</code> (аутентификация) и <code>domain</code> (бизнес-события), хранит дельты изменений на уровне полей в <code>event_data</code> JSONB</td></tr></tbody></table>

</details>

### Связи данных

Узел `repo` схема реализует сложные шаблоны связей для гибкого моделирования данных:

**Иерархические структуры**

* Организации используют пути ltree для эффективных древовидных запросов
* Справочные элементы (`ci_base`) поддерживают необязательные иерархии
* Автоматическое поддержание пути с помощью триггеров базы данных

**Шаблоны наследования**

* Наследование таблиц: `customizable_entity` → бизнес-сущности (`organization`, `user`, `device`, `asset`, `inventory`, `asset_group`)
* Наследование ID: `ci_base` → таблицы справочных типов
* Разделение типов через `entity_type_id` : Изучите исходные схемы ( `discriminator` полями

**Полиморфные связи**

Некоторые таблицы используют полиморфные ссылки без ограничений внешнего ключа для максимальной гибкости:

* `acl_role_permission.target_entity_id` → любой `customizable_entity`
* `acl_user_scope.target_entity_id` → любой `customizable_entity`
* `entity_tag.entity_id` → любой `customizable_entity`

Эти связи проверяются на уровне приложения.

### Дополнительная информация

#### Проверка данных

Узел `repo` схема обеспечивает целостность данных с помощью нескольких механизмов:

**Ограничения базы данных**

* Ограничения UNIQUE с поддержкой мягкого удаления (частичные индексы WHERE `deleted_at` IS NULL)
* Ограничения CHECK (например, `device_relation` обеспечивает `master_id` ≠ `slave_id`)
* Ограничения NOT NULL для обязательных полей
* Значения DEFAULT для временных меток и булевых флагов

**Проверка на уровне приложения**

* Проверка типа сущности для полиморфных ссылок
* Проверка каталога для ссылок пользовательских полей
* Проверка типа пользовательского поля
* Управление массивами полей со множественными значениями

#### Оптимизация запросов

Таблицы организованы с использованием определённых стратегий индексирования:

**Стандартные индексы:**

* Все внешние ключи имеют отдельные индексы
* Временные индексы по `created_at`, `updated_at`, `deleted_at`
* Составные индексы для часто соединяемых столбцов

**Специализированные индексы:**

* Индексы GiST по путям ltree для иерархических запросов
* Частичные уникальные индексы, поддерживающие мягкое удаление
* Индексы значений пользовательских полей для фильтрации и сортировки
* Индексы audit\_event по времени + сущности для эффективного поиска

**Соображения производительности:**

* Рекомендуется пул соединений (PgBouncer)
* Регулярное обслуживание VACUUM для больших таблиц
* Возможное будущее разделение таблицы `device` таблица по `organization_id`
* Материализованные представления для сложных вычислений контроля доступа


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://navixy.com/docs/analytics/ru/iot-query/schema-overview/bronze-layer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
