# Camada de dados brutos

A camada Raw data contém 3 esquemas de dados distintos, cada um servindo a diferentes aspectos da plataforma de telemática e inteligência de negócios:

* [`raw_business_data`](#raw_business_data-structure) - contendo tabelas, atributos e valores relacionados a informações de negócios, como veículos, funcionários, geofences adicionados por usuários, etc.
* [`raw_telematics_data`](#raw_telematics_data-structure) - contendo tabelas, atributos e valores relacionados aos dados telemáticos transmitidos por dispositivos sob monitoramento, como localizações, entradas, saídas e eventos.
* [`repo`](#repo-data-structure) - contendo tabelas para gerenciamento de ativos e inventário, incluindo tipos de ativos configuráveis, campos personalizados, relacionamentos entre ativos e dados geoespaciais para rastreamento de recursos organizacionais.

Cada esquema é otimizado para seu domínio de dados específico e padrões de acesso, fornecendo cobertura abrangente das necessidades operacionais, telemáticas e de gerenciamento de ativos.

## `raw_business_data` structure

Este esquema contém mais de 40 tabelas cuidadosamente selecionadas para cobrir vários aspectos de negócios e casos de uso. Essas tabelas representam suas entidades principais de negócios, estrutura organizacional e dados operacionais.

<figure><img src="https://38152389-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoFNFEIINiGFbhi3Px3dE%2Fuploads%2FLxWgTRWILnl4LOQt1IZL%2Fraw_business_data.svg?alt=media&#x26;token=66789735-63b4-4328-911c-322cf3283b62" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
O diagrama interativo do esquema raw\_business\_data está disponível em **dbdiagram.io**: <https://dbdiagram.io/d/V3-bronze-layer-68ecfd1c2e68d21b4131089a>
{% endhint %}

Encontre os detalhes do esquema raw business data abaixo.

{% code title="esquema raw\_business\_data" expandable="true" %}

```sql
Tabela "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
}

Tabela "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)"
}

Tabela "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
}

Tabela "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]
}

Tabela "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
}

Tabela "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]
}

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

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

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

Tabela "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]
}

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

Tabela "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]
}

Tabela "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]
}

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

Tabela "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
}

Tabela "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]
}

Tabela "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
}

Tabela "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]
}

Tabela "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]
}

Tabela "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]
}

Tabela "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]
}

Tabela "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
}

Tabela "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]
}

Tabela "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]
}

Tabela "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)"
}

Tabela "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]
}

Tabela "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]
}

Tabela "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
}

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

Tabela "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
}


Tabela "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]
}

Tabela "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
}

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

Tabela "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]
}

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

Tabela "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]
}

Tabela "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]
}

Tabela "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
}

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

Tabela "raw_device_data" {
  "device_id" integer
  "device_time" timestamp
  "created_at" timestamp
  "gps_fix_type" integer
  "longitude" integer
  "latitude" integer
  "altitude" integer
  "speed" integer
  "satellites" integer
  "hdop" integer
  "event_id" integer
  "inputs" jsonb
  "states" jsonb
}

Tabela "groups_objects" {
  "groups_client_id" integer
  "objects_client_id" integer

  Índices {
    (groups_client_id, objects_client_id) [pk]
  }
}

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:"devices"."device_id" < "raw_device_data"."device_id"

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

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

```

{% endcode %}

### Frequência de atualização

Os dados neste esquema são sincronizados com o DB principal. As atualizações ocorrem incrementalmente conforme mudanças acontecem no banco de dados MySQL de origem, tipicamente em menos de 5 minutos após a alteração na fonte.

### `description_parameters`

O sistema inclui dados de referência para padronizar valores em todo o banco de dados:

<table><thead><tr><th width="167.1817626953125">Tipo de referência</th><th width="173.9090576171875">Descrição</th><th>Valores exemplares</th></tr></thead><tbody><tr><td>Definições de tipo</td><td>Tipos de entidade padrão</td><td><code>vehicle_type: car, truck, bus</code></td></tr><tr><td>Códigos de status</td><td>Valores de status de tarefas e do sistema</td><td><code>tasks_status: unassigned, assigned, done</code></td></tr><tr><td>Definições de unidade</td><td>Unidades de medição para sensores</td><td><code>units_type: liter, gallon, celsius</code></td></tr><tr><td>Classificações de entidade</td><td>Categorias de entidade de negócio</td><td><code>entities_type: place, task, customer</code></td></tr></tbody></table>

### Tabelas-chave por categoria

As tabelas no **`raw_business_data`** esquema estão organizadas em categorias funcionais para facilitar a navegação. A tabela abaixo resume as tabelas-chave por seu propósito de negócio:

Entidades principais de negócio

<details>

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

**Descrição**: Contas de usuário contendo informações de perfil, filiação à empresa, configurações de localização (fuso horário, localidade) e relacionamentos hierárquicos via master\_id para estruturas de conta em vários níveis

<table><thead><tr><th width="145">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>user_id</code> - Identificador único do usuário<br>- <code>company_label</code> - Nome da empresa associada ao usuário<br>- <code>first_name</code> - Nome de usuário<br>- <code>last_name</code> - Sobrenome do usuário<br>- <code>middle_name</code> - Nome do meio (patronímico) do usuário<br>- <code>locale</code> - Configurações de idioma do usuário<br>- <code>timezone_label</code> - Fuso horário em formato IANA<br>- <code>master_id</code> - ID primário do usuário (se o atual for subordinado)<br>- <code>registration_datetime</code> - Data de registro no sistema<br>- <code>birth_date</code> - Data de nascimento do usuário</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Usuário pai via <code>master_id</code>, vinculado a <code>employees</code>, <code>departments</code>, <code>places</code>, <code>tasks</code> através de <code>user_id</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Entidade central que conecta dados organizacionais; <code>master_id</code> habilita hierarquias de usuários para estruturas de conta em vários níveis</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Registros de funcionários e motoristas usados para representar pessoas que trabalham para a organização, incluindo informações pessoais, detalhes de habilitação, atribuições departamentais, chaves de hardware para identificação iButton/RFID e dados de localização com suporte a geofencing

<table><thead><tr><th width="143">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>employee_id</code> - Identificador da entidade funcionário<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>department_id</code> - ID do departamento ao qual o funcionário está atribuído<br>- <code>first_name</code> - O atributo first_name da tabela employees<br>- <code>last_name</code> - O atributo last_name da tabela employees<br>- <code>middle_name</code> - O atributo middle_name da tabela employees<br>- <code>driver_license_number</code> - Número da carteira de motorista<br>- <code>driver_license_categories</code> - Categorias da carteira de motorista<br>- <code>driver_license_issue_date</code> - Data de emissão da carteira de motorista<br>- <code>driver_license_valid_till</code> - Data até a qual a carteira de motorista é válida<br>- <code>hardware_key</code> - Chave de hardware<br>- <code>email</code> - Email do funcionário<br>- <code>phone_number</code> - Telefone do funcionário sem o sinal "+"<br>- <code>address</code> - Endereço da localização<br>- <code>personnel_number</code> - Número de pessoal do funcionário/motorista<br>- <code>citizen_id_number</code> - Número de identificação civil (Social Security number)<br>- <code>latitude</code> - Localização associada a este funcionário<br>- <code>longitude</code> - Localização associada a este funcionário<br>- <code>radius</code> - Localização associada a este funcionário em metros<br>- <code>fuel_consumption</code> - O atributo fuel_consumption da tabela employees<br>- <code>fuel_cost</code> - O atributo fuel_cost da tabela employees<br>- <code>is_deleted</code> - O atributo is_deleted da tabela employees</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vínculos com <code>users</code>, <code>departments</code>, <code>objects</code> (rastreado pelo tracker atribuído), rastreado em <code>driver_history</code> e <code>checkins</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>A chave de hardware permite identificação do motorista via iButton ou RFID; suporta geofencing com <code>latitude</code>, <code>longitude</code>, <code>radius</code> campos</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Unidades organizacionais com dados de localização geográfica (latitude, longitude, radius) permitindo análises baseadas em geofence para relatórios por departamento e associação de localização do funcionário

<table><thead><tr><th width="156">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>department_id</code> - Identificador da entidade departamento<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>department_label</code> - O atributo department_label da tabela departments<br>- <code>latitude</code> - Localização associada a este departamento<br>- <code>longitude</code> - Localização associada a este departamento<br>- <code>radius</code> - Tamanho da geolocalização em metros<br>- <code>address</code> - O atributo address da tabela departments</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vincula funcionários à estrutura organizacional através de <code>department_id</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Campos de localização suportam análises baseadas em geofence para relatórios por departamento</td></tr></tbody></table>

</details>

Rastreamento e monitoramento

<details>

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

**Descrição**: Registro físico de dispositivos de rastreamento com identificadores de hardware (IMEI), informações do cartão SIM, status de conectividade de rede (força do sinal, roaming, operadora) e listagem de status para gerenciamento do ciclo de vida do dispositivo

<table><thead><tr><th width="138">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>device_id</code> - ID do dispositivo<br>- <code>owner_id</code> - ID do proprietário do dispositivo na cuja conta o beacon foi adicionado<br>- <code>device_imei</code> - IMEI do dispositivo<br>- <code>phone</code> - Número do cartão SIM do dispositivo<br>- <code>status_listing_id</code> - ID do status do dispositivo<br>- <code>network_label</code> - Nome da rede à qual o cartão SIM está conectado<br>- <code>signal_level</code> - Nível de sinal do dispositivo<br>- <code>has_roaming</code> - Indicador de disponibilidade de roaming<br>- <code>is_sim_blocked</code> - Indicador de bloqueio do cartão SIM<br>- <code>created_at</code> - Data e hora em que a entrada foi criada</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Entidade principal vinculada a <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>Notas especiais</strong></td><td>Todos os dados telemáticos em <code>raw_telematics_data</code> esquema fazem referência a esta tabela via <code>device_id</code></td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Registro central de entidades monitoradas (veículos, ativos, pessoal) vinculando dispositivos físicos à estrutura organizacional por meio de client\_id e group\_id, representando a "unidade rastreável" com um objeto ativo por dispositivo

<table><thead><tr><th width="148">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>client_id</code> - Identificador da entidade cliente<br>- <code>device_id</code> - Identificador da entidade dispositivo<br>- <code>object_label</code> - Nome do objeto<br>- <code>model</code> - Modelo do dispositivo<br>- <code>group_id</code> - ID do grupo de entidade<br>- <code>create_datetime</code> - Data e hora de criação de uma nova linha no servidor<br>- <code>is_deleted</code> - O atributo is_deleted da tabela objects<br>- <code>is_clone</code> - Indicador de clone</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Centro central conectando dispositivos a usuários (<code>client_id</code>), detalhes do veículo, histórico de rastreamento, tarefas e regras</td></tr><tr><td><strong>Notas especiais</strong></td><td>Representa a "unidade rastreável" no sistema; um objeto por dispositivo em uso ativo</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Registro central de entidades monitoradas (veículos, ativos, pessoal) vinculando dispositivos físicos à estrutura organizacional por meio de client\_id e group\_id, representando a "unidade rastreável" com um objeto ativo por dispositivo

<table><thead><tr><th width="135">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>model_id</code> - Identificador do modelo da entidade<br>- <code>model</code> - O atributo model da tabela models<br>- <code>vendor</code> - Nome da empresa que lançou o rastreador<br>- <code>alternative_label</code> - O atributo alternative_label da tabela models<br>- <code>analog_amount</code> - Número de entradas analógicas do rastreador<br>- <code>digital_amount</code> - Número de entradas discretas do rastreador<br>- <code>outputs_amount</code> - Número de saídas discretas do rastreador<br>- <code>has_battery_level</code> - Determina se o rastreador transmite leituras de carga da bateria<br>- <code>has_altitude</code> - Determina se o rastreador transmite altitude<br>- <code>has_phone</code> - Existe um cartão SIM?<br>- <code>has_gsm_level</code> - Um rastreador pode transmitir a força do sinal GSM?<br>- <code>has_gsm_name</code> - O rastreador pode transmitir o nome da rede GSM ou o código da operadora (MCC + MNC)?<br>- <code>has_gsm_roaming</code> - O rastreador pode transmitir o status de roaming?<br>- <code>has_detach_button</code> - O rastreador possui um sensor de destacamento?<br>- <code>type_output_control</code> - Perfil de controle de saída do rastreador<br>- <code>type_special_control</code> - Contém configurações especializadas e módulos funcionais para modelos individuais de dispositivos, como o modo de direção perigosa (hbm_telfm) para equipamentos Teltonika<br>- <code>is_clone</code> - O modelo é um clone de outro modelo?</td></tr><tr><td><strong>Conteúdo</strong></td><td>Bandeiras booleanas de capacidade indicam quais campos de dados estão disponíveis a partir deste tipo de dispositivo</td></tr><tr><td><strong>Notas especiais</strong></td><td>Use as bandeiras de capacidade para determinar sensores e entradas válidas ao consultar dados telemáticos</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Configuração abrangente de sensores vinculando entradas do dispositivo à lógica de negócio, incluindo mapeamentos de entradas, unidades de medida, fatores de conversão (multiplicador/divisor), tabelas de calibração para sensores de combustível, limites de precisão e lógica de agrupamento para leituras agregadas de sensores

<table><thead><tr><th width="142">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>sensor_id</code> - Identificador da entidade sensor<br>- <code>device_id</code> - Identificador da entidade dispositivo<br>- <code>sensor_label</code> - Nome do sensor para a IU<br>- <code>input_label</code> - O nome do campo da mensagem (atributo) de onde os dados do sensor são obtidos. Se igual a "input_status", é um sensor discreto<br>- <code>sensor_type</code> - Tipo de sensor<br>- <code>units_type</code> - Unidades de medida<br>- <code>multiplier</code> - Multiplicador - o número pelo qual multiplicar o valor do campo. Apenas para sensores de medição<br>- <code>divider</code> - Divisor - o número pelo qual dividir o valor do campo. Apenas para sensores de medição<br>- <code>accuracy</code> - Uma porcentagem especificada para calcular o erro absoluto do volume do tanque. Esse erro é usado para determinar quando ocorrem reabastecimentos ou drenagens. Isso é usado apenas para sensores de combustível<br>- <code>calibration_data</code> - O atributo calibration_data da tabela sensor_description<br>- <code>input_id</code> - Número de entrada para sensor discreto<br>- <code>group_id</code> - Sensores do mesmo tipo com o mesmo group_id e source_id são considerados pertencentes ao mesmo grupo. Seus dados são somados ou promediados, dependendo do valor de group_type. Isto é necessário para sensores agregados. É usado em sensores de medição<br>- <code>group_type</code> - 0 - soma os valores dos sensores dentro de um grupo, 1 - média<br>- <code>sensor_units</code> - Nome da unidade inserida pelo usuário se units_type=0 (personalizado)<br>- <code>parameters</code> - Objeto opcional com parâmetros adicionais parent_ids - array opcional de parent_ids para sensor composto. volume - double. Opcional. Volume para sensor composto. parent_ids - opcional. array de int. Array de parent_ids para sensor composto. volume - opcional. Double. Volume para sensor composto. min - opcional. Double. Valor bruto mínimo aceitável para um sensor. max - opcional. Double. Valor bruto máximo aceitável para um sensor. max_lowering_by_time - opcional. Double. Valor máximo legal de redução por hora. max_lowering_by_mileage - opcional. Double. Valor máximo legal de redução por 100 km. ignore_drains_in_move - opcional. Boolean. Padrão é false. Se true, as drenagens de combustível não serão detectadas durante movimento. ignore_refuels_in_move - opcional. Boolean. Padrão é false. Se true, os reabastecimentos não serão detectados durante movimento. refuel_gap_minutes - opcional. Integer. Padrão é 5. O tempo em minutos após o início do movimento em que reabastecimentos serão detectados durante o movimento. custom_field_name - opcional. Boolean. Padrão false. O parâmetro determina se o campo input_name é um valor personalizado inserido pelo usuário. Isso faz sentido apenas se o modelo do rastreador tiver o recurso has_custom_fields</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vincula entradas do dispositivo (de <code>raw_telematics_data.inputs</code>) à lógica de negócio através de <code>device_id</code> e <code>input_label</code> matching</td></tr><tr><td><strong>Notas especiais</strong></td><td><code>calibration_data</code> (JSONB) armazena tabelas de calibração específicas do sensor para sensores de nível de combustível; <code>multiplier</code> e <code>divider</code> converter valores brutos para unidades</td></tr></tbody></table>

</details>

Gestão de ativos

<details>

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

**Descrição**: Registro abrangente de veículos contendo especificações (dimensões, peso, capacidade), documentação (VIN, registro, seguro), parâmetros operacionais (consumo de combustível, volume do tanque) e atribuição atual do rastreador via object\_id para gestão de frota e monitoramento de conformidade

<table><thead><tr><th width="144">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>vehicle_id</code> - Identificador da entidade veículo<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>garage_id</code> - Identificador da entidade garagem<br>- <code>vehicle_label</code> - O atributo vehicle_label da tabela vehicles<br>- <code>registration_number</code> - Número de registro/placa do veículo<br>- <code>vin</code> - O atributo vin da tabela vehicles<br>- <code>manufacture_year</code> - O atributo manufacture_year da tabela vehicles<br>- <code>fuel_type</code> - O atributo fuel_type da tabela vehicles<br>- <code>fuel_cost</code> - O atributo fuel_cost da tabela vehicles<br>- <code>fuel_tank_volume</code> - O atributo fuel_tank_volume da tabela vehicles<br>- <code>max_speed</code> - O atributo max_speed da tabela vehicles<br>- <code>model</code> - O atributo model da tabela vehicles<br>- <code>color</code> - O atributo color da tabela vehicles<br>- <code>trailer</code> - O atributo trailer da tabela vehicles<br>- <code>additional_info</code> - O atributo additional_info da tabela vehicles<br>- <code>vehicle_type</code> - O atributo vehicle_type da tabela vehicles<br>- <code>vehicle_subtype</code> - O atributo vehicle_subtype da tabela vehicles<br>- <code>vehicle_status_id</code> - Identificador da entidade status do veículo<br>- <code>chassis_number</code> - O atributo chassis_number da tabela vehicles<br>- <code>frame_number</code> - O atributo frame_number da tabela vehicles<br>- <code>trailer_reg_number</code> - O atributo trailer_reg_number da tabela vehicles<br>- <code>payload_weight</code> - O atributo payload_weight da tabela vehicles<br>- <code>payload_height</code> - O atributo payload_height da tabela vehicles<br>- <code>payload_length</code> - O atributo payload_length da tabela vehicles<br>- <code>payload_width</code> - O atributo payload_width da tabela vehicles<br>- <code>passenger_capacity</code> - Número máximo de passageiros<br>- <code>gross_weight</code> - O atributo gross_weight da tabela vehicles<br>- <code>standard_fuel_consumption</code> - Consumo médio normal de combustível em litros por 100 km<br>- <code>fuel_grade</code> - O atributo fuel_grade da tabela vehicles<br>- <code>wheel_arrangement</code> - O atributo wheel_arrangement da tabela vehicles<br>- <code>tyre_size</code> - Tamanho do veículo: dimensões e tamanho das rodas<br>- <code>tyres_number</code> - Número de rodas<br>- <code>liability_insurance_policy_number</code> - O atributo liability_insurance_policy_number da tabela vehicles<br>- <code>liability_insurance_valid_till</code> - Data até a qual o seguro de responsabilidade é válido<br>- <code>free_insurance_policy_number</code> - O atributo free_insurance_policy_number da tabela vehicles<br>- <code>free_insurance_valid_till_date</code> - Data até a qual o seguro gratuito é válido</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vínculos com <code>objects</code> (rastreador atual), <code>garages</code> (local de serviço), <code>vehicle_service_tasks</code>; rastreado em <code>vehicle_trackers_history</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Campos de dimensão física (<code>payload_length</code>, <code>payload_width</code>, <code>payload_height</code>, <code>gross_weight</code>) suportam análises de planejamento de carga; datas de seguro permitem monitoramento de conformidade</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Localizações de serviço e manutenção com coordenadas geográficas (latitude, longitude, radius), informações de contato de mecânicos e despachantes, possibilitando detecção de visitas de serviço baseada em geofence e análise de proximidade

<table><thead><tr><th width="135">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>garage_id</code> - Identificador da entidade garagem<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>latitude</code> - Objeto de localização<br>- <code>longitude</code> - Objeto de localização<br>- <code>radius</code> - Tamanho da geolocalização em metros<br>- <code>address</code> - Objeto de localização<br>- <code>organization_label</code> - ID do depósito<br>- <code>mechanic_name</code> - Nome do mecânico<br>- <code>dispatcher_name</code> - Nome do despachante</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Referenciado por <code>vehicles.garage_id</code> para atribuição de local de serviço</td></tr><tr><td><strong>Notas especiais</strong></td><td>Campos de localização habilitam detecção de visitas de serviço baseada em geofence e análise de proximidade</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Agendamento de manutenção e acompanhamento de histórico de serviço com múltiplos tipos de gatilho (baseado em data, baseado em quilometragem, baseado em horas de motor), intervalos recorrentes de tarefas, notificações multicanal (email, SMS, push) e distinção entre eventos de manutenção planejados (is\_repeat) e não planejados

<table><thead><tr><th width="132">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>service_task_id</code> - Identificador da entidade tarefa de serviço<br>- <code>vehicle_id</code> - Identificador da entidade veículo<br>- <code>description</code> - O atributo description da tabela vehicle_service_tasks<br>- <code>status</code> - O valor do atributo status<br>- <code>cost</code> - O atributo cost da tabela vehicle_service_tasks<br>- <code>start_date</code> - A data e hora associadas ao atributo start_date<br>- <code>end_date</code> - A data e hora associadas ao atributo end_date<br>- <code>completion_date</code> - A data e hora associadas ao atributo completion_date<br>- <code>predicted_datetime</code> - A data e hora associadas ao atributo predicted_datetime<br>- <code>mileage_limit</code> - O atributo mileage_limit da tabela vehicle_service_tasks<br>- <code>engine_hours_limit</code> - O atributo engine_hours_limit da tabela vehicle_service_tasks<br>- <code>start_mileage</code> - O atributo start_mileage da tabela vehicle_service_tasks<br>- <code>start_engine_hours</code> - O atributo start_engine_hours da tabela vehicle_service_tasks<br>- <code>mileage_notification_interval</code> - O atributo mileage_notification_interval da tabela vehicle_service_tasks<br>- <code>engine_hours_notification_interval</code> - O atributo engine_hours_notification_interval da tabela vehicle_service_tasks<br>- <code>date_notification_interval</code> - Converter um inteiro N para N dias<br>- <code>mileage_repeat_interval</code> - O atributo mileage_repeat_interval da tabela vehicle_service_tasks<br>- <code>engine_hours_repeat_interval</code> - O atributo engine_hours_repeat_interval da tabela vehicle_service_tasks<br>- <code>date_repeat_interval</code> - Converter um inteiro N para N dias<br>- <code>notification_emails</code> - O atributo notification_emails da tabela vehicle_service_tasks<br>- <code>notification_sms_phone_numbers</code> - O atributo notification_sms_phone_numbers da tabela vehicle_service_tasks<br>- <code>is_notification_push_enabled</code> - O atributo is_notification_push_enabled da tabela vehicle_service_tasks<br>- <code>completion_mileage</code> - O atributo completion_mileage da tabela vehicle_service_tasks<br>- <code>completion_engine_hours</code> - O atributo completion_engine_hours da tabela vehicle_service_tasks<br>- <code>is_repeat</code> - O atributo is_repeat da tabela vehicle_service_tasks<br>- <code>is_unplanned</code> - O atributo is_unplanned da tabela vehicle_service_tasks<br>- <code>comment</code> - O atributo comment da tabela vehicle_service_tasks</td></tr><tr><td><strong>Conteúdo</strong></td><td>Suporta três tipos de gatilho: baseado em data, baseado em quilometragem, baseado em horas de motor; configurações de notificação para email, SMS, push</td></tr><tr><td><strong>Notas especiais</strong></td><td><code>is_repeat</code> e campos de intervalo habilitam cronogramas de manutenção recorrentes; <code>is_unplanned</code> distingue manutenção programada vs. reativa</td></tr></tbody></table>

</details>

Localização e roteamento

<details>

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

**Descrição**: Áreas geofenced definindo perímetros virtuais usando círculos ou polígonos para monitoramento de eventos de entrada e saída de veículos/ativos, suportando automação baseada em regras e análises de localização com codificação de cores para diferenciação visual

<table><thead><tr><th width="150">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>zone_id</code> - Identificador da entidade zona<br>- <code>client_id</code> - Identificador da entidade cliente<br>- <code>zone_label</code> - O atributo zone_label da tabela zones<br>- <code>zone_type</code> - O atributo zone_type da tabela zones<br>- <code>latitude</code> - Objeto opcional, o bounding box que pode conter totalmente o resultado retornado<br>- <code>longitude</code> - Objeto opcional, o bounding box que pode conter totalmente o resultado retornado<br>- <code>circle_center_latitude</code> - O atributo circle_center_latitude da tabela zones<br>- <code>circle_center_longitude</code> - O atributo circle_center_longitude da tabela zones<br>- <code>radius</code> - Tamanho da geolocalização em metros<br>- <code>address</code> - O atributo address da tabela zones<br>- <code>color</code> - O atributo color da tabela zones</td></tr><tr><td><strong>Conteúdo</strong></td><td>Tipos de zona incluem circle, polygon (definido via <code>geofence_points</code>), e classificações de áreas especiais</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Referenciado por <code>rules2zones</code>, <code>users2zones</code>; vértices do polígono armazenados em <code>geofence_points</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Funções PostGIS podem ser usadas para verificar ponto-em-polígono para análise complexa de geofences</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Pontos de interesse com coordenadas geográficas, definições de raio e suporte extensível a campos personalizados para armazenar informações de contato do cliente e dados específicos do negócio, possibilitando integração CRM/ERP via external\_id e relatórios baseados em localização

<table><thead><tr><th width="129">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>place_id</code> - Identificador da entidade Place<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>place_label</code> - O atributo place_label da tabela places<br>- <code>latitude</code> - Objeto de localização<br>- <code>longitude</code> - Objeto de localização<br>- <code>radius</code> - Tamanho da geolocalização em metros<br>- <code>address</code> - O atributo address da tabela places<br>- <code>description</code> - O atributo description da tabela places<br>- <code>external_id</code> - ID para integração com sistemas externos (CRM)<br>- <code>custom_fields</code> - Campos adicionais<br>- <code>assigned_datetime</code> - Data e hora da atribuição do ponto de interesse ao usuário</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Estendido com valores de campos personalizados através de <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>Notas especiais</strong></td><td><code>custom_fields</code> JSONB fornece acesso rápido; tabelas relacionadas permitem filtragem e ordenação por atributos personalizados</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Coordenadas de vértices ordenadas (campo number determina a sequência) definindo limites do polígono para formas de geofence complexas, possibilitando perímetros geográficos precisos além de zonas circulares simples, usado com PostGIS ST\_MakePolygon para operações geométricas

<table><thead><tr><th width="133">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>zone_id</code> - Um ID da zona à qual este formulário está anexado<br>- <code>number</code> - Número sequencial<br>- <code>latitude</code> - Localização<br>- <code>longitude</code> - Localização</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Múltiplos registros por <code>zone_id</code> definir limites do polígono; <code>number</code> campo determina a ordem dos vértices</td></tr><tr><td><strong>Notas especiais</strong></td><td>Consultar com <code>ORDER BY number</code> para reconstruir o caminho do polígono; usar com PostGIS ST_MakePolygon para operações geométricas</td></tr></tbody></table>

</details>

Gestão de tarefas e fluxo de trabalho

<details>

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

**Descrição**: Atribuições de ordens de serviço com validação de localização (latitude, longitude, radius), janelas de tempo (time\_from, time\_to), requisitos de duração de visita (stay\_duration\_minutes, arrival\_duration\_minutes), estrutura hierárquica via parent\_task\_id e rastreamento de status para gerenciamento de serviços de campo e operações de entrega

<table><thead><tr><th width="130">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>task_id</code> - Identificador da entidade Task<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>parent_task_id</code> - Identificador da entidade Parent task<br>- <code>task_label</code> - O atributo task_label da tabela tasks<br>- <code>status</code> - O valor do atributo status<br>- <code>task_type</code> - Tipo de tarefa: task, route ou checkpoint<br>- <code>latitude</code> - O atributo latitude da tabela tasks<br>- <code>longitude</code> - O atributo longitude da tabela tasks<br>- <code>radius</code> - Tamanho da geolocalização em metros<br>- <code>arrival_datetime</code> - Quando o rastreador chega na área da tarefa. IGNORADO ao criar/atualizar<br>- <code>created_at</code> - O atributo created_at da tabela tasks<br>- <code>status_change_datetime</code> - Data e hora da atualização da tarefa<br>- <code>time_from</code> - A data e hora associadas ao atributo time_from<br>- <code>time_to</code> - A data e hora associadas ao atributo time_to<br>- <code>stay_duration</code> - O atributo stay_duration da tabela tasks<br>- <code>stay_duration_minutes</code> - Duração da visita. O tempo que um trabalhador móvel deve permanecer no local da tarefa para concluir com sucesso a tarefa. Visitas múltiplas são cumulativas<br>- <code>arrival_duration_minutes</code> - Ignorar visitas aleatórias mais curtas que a duração especificada. Ao calcular a duração mínima, visitas mais curtas que a duração especificada serão ignoradas<br>- <code>max_delay_minuts</code> - Atraso aceitável. A quantidade máxima de tempo que um funcionário pode se atrasar. Qualquer tarefa concluída durante esse tempo será marcada como "late"<br>- <code>is_stay_control_enabled</code> - O atributo is_stay_control_enabled da tabela tasks<br>- <code>address</code> - O atributo address da tabela tasks<br>- <code>description</code> - Atributo description da tabela tasks<br>- <code>custom_fields</code> - O atributo custom_fields da tabela tasks<br>- <code>external_id</code> - Identificador de entidade externa<br>- <code>order_sort</code> - O atributo order_sort da tabela tasks<br>- <code>created_by</code> - Fonte da tarefa criada</td></tr><tr><td><strong>Conteúdo</strong></td><td>Suporta tarefas hierárquicas via <code>parent_task_id</code>; janelas de tempo definidas por <code>time_from</code>/<code>time_to</code>; validação de geofence com localização e radius</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vínculos com <code>forms</code> (coleta de dados), <code>task_history</code> (alterações de status), <code>objects</code> (rastreadores atribuídos)</td></tr><tr><td><strong>Notas especiais</strong></td><td><code>stay_duration</code> e <code>arrival_duration_minutes</code> habilitam monitoramento de conformidade para tarefas de entrega e serviço</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Formulários configuráveis de coleta de dados para capturar informações estruturadas durante a conclusão da tarefa ou check-ins no aplicativo móvel, com campos e valores armazenados como JSON, validação opcional de localização (is\_submission\_in\_zone) e requisitos de submissão obrigatória quando anexados a tarefas

<table><thead><tr><th width="141">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>form_id</code> - Identificador da entidade Form<br>- <code>task_id</code> - Um ID da tarefa à qual este formulário está anexado<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>form_label</code> - Rótulo do formulário definido pelo usuário<br>- <code>campos</code> - Se true, o formulário só pode ser submetido na zona da tarefa<br>- <code>values</code> - Um mapa com IDs de campo como chaves e objetos field_value como valores. Chave usada para vincular o campo ao seu valor correspondente<br>- <code>submitted_at</code> - Data em que os valores do formulário foram submetidos pela última vez<br>- <code>submission_latitude</code> - Localização na qual os valores do formulário foram submetidos pela última vez<br>- <code>submission_longitude</code> - Localização na qual os valores do formulário foram submetidos pela última vez<br>- <code>submission_address</code> - Localização na qual os valores do formulário foram submetidos pela última vez<br>- <code>is_submission_in_zone</code> - Se true, o formulário só pode ser submetido na zona da tarefa<br>- <code>description</code> - Data em que este formulário foi criado (ou anexado à tarefa)<br>- <code>created_at</code> - Data em que este formulário foi criado (ou anexado à tarefa)</td></tr><tr><td><strong>Conteúdo</strong></td><td><code>campos</code> define a estrutura do formulário (JSON); <code>values</code> contém os dados submetidos (JSON)</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vínculos com <code>tasks</code> (ordem de serviço associada), <code>objects</code> (remetente), referenciado em <code>checkins</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Flag de validação de localização <code>is_submission_in_zone</code> habilita regras de submissão de formulários baseadas em geofence</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Registros de presença e atividade baseados em localização submetidos via aplicativo móvel, rastreando horários planejados versus reais de chegada (planned\_datetime vs actual\_datetime) com coordenadas geográficas e medições de precisão de localização (radius) para relatórios de pontualidade

<table><thead><tr><th width="129">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>checkin_id</code> - Identificador da entidade Checkin<br>- <code>employee_id</code> - O identificador da entidade employee também é o identificador para drivers<br>- <code>object_id</code> - Dispositivo do employee<br>- <code>form_id</code> - Identificador da entidade Form<br>- <code>user_id</code> - Usuário employee<br>- <code>planned_datetime</code> - Horário do dispositivo quando o check-in foi realizado<br>- <code>actual_datetime</code> - Horário do servidor quando a requisição/mensagem foi processada<br>- <code>latitude</code> - Localização na qual os checkins foram submetidos<br>- <code>longitude</code> - Localização na qual os checkins foram submetidos<br>- <code>radius</code> - Erro de posicionamento em um ponto em metros<br>- <code>address</code> - Endereço do check-in<br>- <code>comment</code> - O atributo comment da tabela checkins</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Conecta empregados a formulários e locais; rastreia desvios do cronograma planejado</td></tr><tr><td><strong>Notas especiais</strong></td><td>Variação de tempo entre <code>planned_datetime</code> e <code>actual_datetime</code> habilita relatórios de pontualidade; radius define tolerância de localização aceitável</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Trilha completa de auditoria dos eventos do ciclo de vida da tarefa capturando todas as mudanças de status, atribuições, atualizações e modificações de campo com timestamps (event\_datetime), atribuição de usuário e tipos de atividade (create, update, assign, status\_change) armazenados no campo payload para conformidade e análise de fluxo de trabalho

<table><thead><tr><th width="137">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>task_history_id</code> - Identificador da entidade Task history<br>- <code>task_id</code> - Identificador da entidade Task<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>activity</code> - Operação que ocorreu. Pode ser "create", "update", "assign" ou "status_change"<br>- <code>event_datetime</code> - Data e hora do evento<br>- <code>payload</code> - Depende da operação. Tipicamente, contém campos que foram alterados durante a operação</td></tr><tr><td><strong>Conteúdo</strong></td><td>Tipos de atividade definidos em <code>description_parameters</code>; <code>payload</code> armazena detalhes específicos do evento (texto)</td></tr><tr><td><strong>Notas especiais</strong></td><td>Essencial para análise de conclusão de tarefas, relatórios de transição de status e rastreamento de atividade de usuários</td></tr></tbody></table>

</details>

Regras e automação

<details>

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

**Descrição**: Regras de detecção de eventos com condições de gatilho configuráveis (excesso de velocidade, violações de geofence, limites de sensores, tempo ocioso) armazenadas em parameters (JSONB), e configurações de notificação multicanal (alert\_email, alert\_sms, alert\_phone, is\_push\_enabled) para monitoramento automatizado e alerta baseado em dados de dispositivo e servidor

<table><thead><tr><th width="131">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>rule_id</code> - Identificador da entidade Rule<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>client_id</code> - Identificador da entidade cliente<br>- <code>event_type</code> - O atributo event_type da tabela rules<br>- <code>event_label</code> - O atributo event_label da tabela rules<br>- <code>event_group</code> - O atributo event_group da tabela rules<br>- <code>description</code> - Atributo description da tabela rules<br>- <code>parameters</code> - Parâmetros do evento. Para mais detalhes sobre parâmetros disponíveis, veja <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> - E-mail para notificações<br>- <code>alert_sms</code> - Números de telefone para notificações por SMS<br>- <code>alert_phone</code> - Telefones para chamadas de voz<br>- <code>is_push_enabled</code> - Se true, notificações push estão disponíveis<br>- <code>created_at</code> - O atributo created_at da tabela rules<br>- <code>is_deleted</code> - O atributo is_deleted da tabela rules<br>- <code>maximum</code> - Limites aplicados a várias regras. Por exemplo, para a regra de tempo ocioso com o motor ligado em minutos<br>- <code>event_comment1</code> - O atributo event_comment1 da tabela rules<br>- <code>event_comment2</code> - O atributo event_comment2 da tabela rules</td></tr><tr><td><strong>Conteúdo</strong></td><td>Parâmetros da regra (JSONB) definem condições de gatilho; suporta notificações por email, SMS, telefone e push</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vincula a objetos via <code>rules2objects</code>, zonas via <code>rules2zones</code></td></tr><tr><td><strong>Notas especiais</strong></td><td><code>event_type</code> define cenário específico de monitoramento (excesso de velocidade, violação de geofence, limite de sensor); <code>maximum</code> campo permite agregação de eventos para alerta baseado em limites</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Relação muitos-para-muitos ligando regras a objetos monitorados com customização de parâmetros por objeto via object\_params (JSONB), permitindo valores de limite diferentes (por exemplo, limites de velocidade) para cada veículo ou ativo dentro da mesma regra

<table><thead><tr><th width="140">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>rule_id</code> - Identificador da entidade Rule<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>param_group_number</code> - O atributo param_group_number da tabela rules2objects<br>- <code>object_params</code> - O atributo object_params da tabela rules2objects</td></tr><tr><td><strong>Conteúdo</strong></td><td><code>object_params</code> (JSONB) permite personalização de regras por objeto (por exemplo, limites de velocidade diferentes por veículo)</td></tr><tr><td><strong>Notas especiais</strong></td><td>Relação muitos-para-muitos permite que uma regra monitore múltiplos objetos com parâmetros diferentes</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Relação muitos-para-muitos associando regras a zonas geofenceadas, permitindo que uma única regra monitore eventos de entrada/saída em múltiplas áreas geográficas para cenários complexos de monitoramento espacial

<table><thead><tr><th width="144">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>rule_id</code> - Identificador da entidade Rule<br>- <code>zone_id</code> - Identificador da entidade Zone</td></tr><tr><td><strong>Notas especiais</strong></td><td>Relação muitos-para-muitos permite monitoramento multi-zona para uma única regra (por exemplo, alertar ao entrar em qualquer uma de várias áreas restritas)</td></tr></tbody></table>

</details>

Status e categorização

<details>

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

**Descrição**: Definições de status personalizadas dentro de listagens de status, incluindo propriedades de exibição (color para exibição no site, order\_sort para posicionamento) usadas para representar estados de trabalho de dispositivo ou empregado com suporte a exclusão lógica via flag is\_deleted

<table><thead><tr><th width="128">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>status_id</code> - Identificador da entidade Status<br>- <code>listing_id</code> - Identificador da entidade Listing<br>- <code>status_label</code> - Valor de status do atributo status_label<br>- <code>color</code> - Cor usada para exibição no site<br>- <code>order_sort</code> - Posição de ordenação dentro da listagem de status<br>- <code>is_deleted</code> - O atributo is_deleted da tabela statuses</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Grupos de status organizados por <code>listing_id</code> (referências <code>status_listings</code>); usado em <code>status_history</code></td></tr><tr><td><strong>Notas especiais</strong></td><td><code>order_sort</code> define sequência de exibição; color permite diferenciação visual em relatórios</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Definições de conjuntos de status controlando quais valores de status estão disponíveis para dispositivos ou empregados, com flags de permissão (is\_supervisor\_controlled, is\_employee\_controlled) determinando se supervisores, empregados ou ambos podem alterar valores de status

<table><thead><tr><th width="144">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>status_listing_id</code> - Identificador da entidade Status listing<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>status_listing_label</code> - Valor de status do atributo status_listing_label<br>- <code>is_supervisor_controlled</code> - Se true, supervisores podem alterar o status de trabalho, por exemplo usando o aplicativo móvel de monitoramento<br>- <code>is_employee_controlled</code> - Se true, empregados podem alterar seu próprio status de trabalho, por exemplo usando o aplicativo móvel de rastreamento<br>- <code>is_deleted</code> - O atributo is_deleted da tabela status_listings</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Referenciado por <code>devices.status_listing_id</code> e <code>statuses.listing_id</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Flags de controle determinam quem pode alterar status: somente supervisor, autoatendimento do empregado ou ambos</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Trilha de auditoria de todas as transições de status de dispositivo com timestamps (changed\_datetime no dispositivo, server\_datetime no servidor), atribuição de usuário (updated\_by) e captura de localização (latitude, longitude, address) permitindo análise geográfica de mudanças de status e relatórios de local de início/fim do dia de trabalho

<table><thead><tr><th width="143">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>status_history_id</code> - Identificador da entidade Status history<br>- <code>device_id</code> - Identificador da entidade dispositivo<br>- <code>old_status_id</code> - Identificador da entidade Old status<br>- <code>new_status_id</code> - Identificador da entidade New status<br>- <code>updated_by</code> - A data e hora associadas ao atributo updated_by<br>- <code>changed_datetime</code> - Data e hora de atribuição de um novo status no dispositivo<br>- <code>server_datetime</code> - Data e hora de atribuição do novo status no servidor<br>- <code>latitude</code> - Localização dos dispositivos durante mudanças de status<br>- <code>longitude</code> - Localização dos dispositivos durante mudanças de status<br>- <code>address</code> - Localização dos dispositivos durante mudanças de status</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vínculos com <code>devices</code>, <code>statuses</code> (antigo e novo), <code>description_parameters</code> (para <code>updated_by</code> role)</td></tr><tr><td><strong>Notas especiais</strong></td><td>Captura de localização permite análise geográfica de transições de status; útil para relatórios de local de início/fim do dia de trabalho</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Rótulos de categorização definidos pelo usuário com codificação de cores que permitem filtragem e busca rápida através de múltiplos tipos de entidade (places, geofences, employees, tasks, trackers, vehicles) para organização flexível

<table><thead><tr><th width="149">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>tag_id</code> - ID da entidade Tag<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>tag_label</code> - O atributo tag_label da tabela tags<br>- <code>color</code> - O atributo color da tabela tags</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Aplicado a entidades via <code>tag_links</code>; escopo definido pelo usuário</td></tr><tr><td><strong>Notas especiais</strong></td><td>Sistema de categorização flexível suportando múltiplas tags por entidade</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Tabela de relação polimórfica associando tags a qualquer tipo de entidade via entity\_type e entity\_id, com campo ordinal para gerenciamento da ordem de exibição, possibilitando marcação flexível multi-entidade

<table><thead><tr><th width="127">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>tag_id</code> - ID da entidade Tag<br>- <code>entity_type</code> - O atributo entity_type da tabela tag_links<br>- <code>entity_id</code> - Identificador da entidade<br>- <code>ordinal</code> - O atributo ordinal da tabela tag_links</td></tr><tr><td><strong>Conteúdo</strong></td><td><code>entity_type</code> identifica tabela (vehicle, employee, task, etc.); <code>ordinal</code> define ordem de exibição</td></tr><tr><td><strong>Notas especiais</strong></td><td>Relação polimórfica permite marcação através de diferentes tipos de entidade</td></tr></tbody></table>

</details>

Grupos e hierarquia

<details>

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

**Descrição**: Estrutura de agrupamento organizacional para trackers permitindo organização visual na interface do usuário com cores personalizáveis (group\_color) e gerenciamento hierárquico em formato de pastas, atualmente servindo função puramente visual

<table><thead><tr><th width="148">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>group_id</code> - Grupo de trackers (ligado por objects.group_id). A divisão em grupos pode ser vista na lista de beacons, por exemplo<br>- <code>client_id</code> - Identificador da entidade cliente<br>- <code>group_label</code> - Título do grupo especificado pelo usuário, 1 a 60 caracteres imprimíveis, ex: "Employees"<br>- <code>group_color</code> - Cor do grupo em formato web (sem #), ex: "FF6DDC". Determina a cor dos marcadores dos trackers no mapa</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Referenciado por <code>objects.group_id</code>; propriedade do cliente via <code>client_id</code> (referências <code>users</code>)</td></tr><tr><td><strong>Notas especiais</strong></td><td>Permite organização em formato de pastas de entidades de monitoramento para relatórios e permissões</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Relação muitos-para-muitos entre groups e objects usando chave primária composta (groups\_client\_id, objects\_client\_id), permitindo que objetos pertençam a múltiplos grupos simultaneamente para estruturas organizacionais flexíveis

<table><thead><tr><th width="135">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>groups_client_id</code> - Identificador da entidade Client para groups<br>- <code>objects_client_id</code> - Identificador da entidade Client para objects</td></tr><tr><td><strong>Notas especiais</strong></td><td>Permite que objetos pertençam a múltiplos grupos simultaneamente; consultar com ambos <code>client_id</code> valores para associação ao grupo</td></tr></tbody></table>

</details>

Campos personalizados e entidades

<details>

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

**Descrição**: Registro de tipos de entidade definindo quais entidades de negócio suportam campos personalizados e sua estrutura de layout de campos (sections, field\_order) armazenada em entity\_label (JSONB), permitindo extensão dinâmica de esquema em places, tasks e outras entidades sem mudanças no banco de dados

<table><thead><tr><th width="141">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>entity_id</code> - Identificador da entidade<br>- <code>user_id</code> - Identificador da entidade usuário<br>- <code>entity_label</code> - id - int. Identificador da entidade. type - enum. Atualmente, apenas "place" é suportado. layout - objeto que descreve o layout dos campos para a entidade. sections - array de objetos. Cada seção pode conter um ou mais campos. Deve existir pelo menos uma seção em um layout. label - string. Nome da seção. field_order - array de strings. Campos internos e IDs de campos personalizados (como strings)<br>- <code>builtin_type</code> - O atributo builtin_type da tabela entities</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Referenciado por <code>custom_fields</code> para definir quais campos personalizados se aplicam a quais tipos de entidade</td></tr><tr><td><strong>Notas especiais</strong></td><td><code>builtin_type</code> vincula a <code>description_parameters</code> para classificações de entidade definidas pelo sistema</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Definições de campos personalizados permitindo extensão dinâmica de esquema para tipos de entidade, com tipos de campo configuráveis (custom\_field\_type), regras de validação e opções em parameters (JSONB), e flags de obrigatoriedade (is\_required) para captura flexível de dados em places, tasks e outras entidades

<table><thead><tr><th width="146">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>custom_field_id</code> - Identificador da entidade Custom field<br>- <code>entity_id</code> - Identificador da entidade<br>- <code>custom_field_label</code> - Nome do campo<br>- <code>custom_field_type</code> - Tipo de dado no campo<br>- <code>description</code> - Descrição do campo<br>- <code>is_required</code> - Isso é obrigatório ou não?<br>- <code>parameters</code> - Parâmetros do campo</td></tr><tr><td><strong>Conteúdo</strong></td><td><code>parameters</code> (JSONB) armazena configuração específica do tipo de campo (regras de validação, opções de dropdown, etc.)</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Define atributos personalizados disponíveis para entidades; o tipo de campo vincula a <code>description_parameters</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Permite extensão dinâmica de esquema sem mudanças no banco de dados; usado extensivamente em <code>places</code> e <code>tasks</code></td></tr></tbody></table>

</details>

Rastreamento histórico

<details>

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

**Descrição**: Trilha completa de auditoria de atribuições de empregado a veículo ao longo do tempo rastreando transições de old\_employee\_id para new\_employee\_id com timestamps (changed\_datetime, server\_datetime), dados de localização (latitude, longitude, address), informações de chave de hardware e atribuição de usuário (updated\_by) possibilitando análises específicas por motorista quando motoristas trocam de veículo

<table><thead><tr><th width="146">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>driver_history_id</code> - Identificador da entidade Driver history<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>old_employee_id</code> - Identificador da entidade Old employee<br>- <code>new_employee_id</code> - Identificador da entidade New employee<br>- <code>hardware_key</code> - O atributo hardware_key da tabela driver_history<br>- <code>changed_datetime</code> - Data e hora em que as alterações foram feitas no dispositivo<br>- <code>server_datetime</code> - Data e hora das alterações feitas no servidor<br>- <code>updated_by</code> - A data e hora associadas ao atributo updated_by<br>- <code>latitude</code> - O atributo latitude da tabela driver_history<br>- <code>longitude</code> - O atributo longitude da tabela driver_history<br>- <code>address</code> - O atributo address da tabela driver_history</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Rastreia atribuições de motoristas a veículos ao longo do tempo; vincula a <code>employees</code> e <code>objects</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Essencial para relatórios específicos por motorista quando motoristas trocam de veículos; captura de localização permite análise de local de mudança de atribuição</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Trilha de auditoria rastreando quais dispositivos GPS (object\_id) foram instalados em quais veículos (vehicle\_id) ao longo do tempo com timestamps de mudança (changed\_datetime), possibilitando atribuição histórica precisa de dados e cálculo de quilometragem quando trackers são movidos entre veículos

<table><thead><tr><th width="144">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>vehicle_tracker_history_id</code> - Identificador da entidade Vehicle tracker history<br>- <code>vehicle_id</code> - Identificador da entidade veículo<br>- <code>object_id</code> - Identificador da entidade objeto<br>- <code>changed_datetime</code> - A data e hora associadas ao atributo changed_datetime</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Rastreia qual dispositivo GPS foi instalado em qual veículo ao longo do tempo</td></tr><tr><td><strong>Notas especiais</strong></td><td>Crítico para análise histórica de dados quando trackers são movidos entre veículos; possibilita atribuição precisa de quilometragem e uso</td></tr></tbody></table>

</details>

Dados de referência e consulta

<details>

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

**Descrição**: Dados de referência em todo o sistema fornecendo rótulos legíveis por humanos (description) para valores inteiros enumerados (key) usados em todo o banco de dados, organizados pelo campo type (ex.: task\_status, fuel\_type, counter\_type, entity\_classification) para tradução consistente de valores em relatórios e exibição na UI

<table><thead><tr><th width="146">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>key</code> - Valor possível no atributo<br>- <code>type</code> - Um atributo composto consistindo do nome da tabela seguido por um underscore e o nome de um atributo na tabela<br>- <code>description</code> - Valor implícito de um atributo</td></tr><tr><td><strong>Conteúdo</strong></td><td>Fornece rótulos legíveis por humanos para valores codificados em todo o banco de dados (status de tarefa, tipos de combustível, tipos de contador, etc.)</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Referenciado via chaves estrangeiras de múltiplas tabelas para categorização padronizada</td></tr><tr><td><strong>Notas especiais</strong></td><td>Essencial para traduzir códigos inteiros em valores legíveis em relatórios; <code>type</code> grupo de campos relacionados a enumerações</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Configurações de odômetro e contador de horas do motor vinculando leituras de sensores do dispositivo (sensor\_id) a medições de distância ou tempo com coeficientes multiplicadores para conversão de unidades (km, miles, hours) e counter\_type de description\_parameters definindo o tipo de medição

<table><thead><tr><th width="140">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>counter_id</code> - ID interno<br>- <code>device_id</code> - Identificador da entidade dispositivo<br>- <code>counter_type</code> - Tipo de contador<br>- <code>sensor_id</code> - Identificador da entidade sensor<br>- <code>multiplier</code> - Coeficiente para converter valores em uma das métricas (km, l, etc.)</td></tr><tr><td><strong>Relacionamentos</strong></td><td>Vincula dispositivos a leituras de sensores que representam contadores de distância ou tempo</td></tr><tr><td><strong>Notas especiais</strong></td><td><code>multiplier</code> converte pulsos de sensores em unidades reais (km, miles, hours); <code>counter_type</code> from <code>description_parameters</code> define o tipo de medição</td></tr></tbody></table>

</details>

<details>

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

**Descrição**: Rótulos personalizados para canais de saída do dispositivo mapeando identificadores numéricos de saída (number) para nomes definidos pelo usuário (label) como "Door Lock" ou "Engine Block" para relatórios legíveis e análise de comandos e estados de saída do dispositivo

<table><thead><tr><th width="140">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td>- <code>device_id</code> - Identificador da entidade dispositivo<br>- <code>number</code> - O atributo number da tabela device_output_name<br>- <code>label</code> - O atributo label da tabela device_output_name</td></tr><tr><td><strong>Conteúdo</strong></td><td>Mapeia números de canais de saída para nomes definidos pelo usuário (por exemplo, "Door Lock", "Engine Block")</td></tr><tr><td><strong>Notas especiais</strong></td><td>Permite relatórios legíveis ao analisar comandos e estados de saída do dispositivo</td></tr></tbody></table>

</details>

## `raw_telematics_data` structure

O **`raw_telematics_data`** schema contém três tipos principais de tabela que trabalham juntos para fornecer dados abrangentes do dispositivo.

<figure><img src="https://38152389-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoFNFEIINiGFbhi3Px3dE%2Fuploads%2FiTtEgzFgyJKTIl0ZCq7E%2Fv1%20schema%20telematics%20bd.svg?alt=media&#x26;token=b298bab4-ca28-41f8-919b-0948bb436614" alt="Bronze layer raw telematics data ERD"><figcaption><p>ERD de dados telemáticos brutos da camada Bronze</p></figcaption></figure>

{% hint style="info" %}
O diagrama interativo do schema raw\_telematics\_data está disponível em **dbdiagram.io**: <https://dbdiagram.io/d/v1-schema-telematics-bd-67a0acef263d6cf9a0d8e750>
{% endhint %}

Encontre detalhes do schema raw telematics data abaixo.

{% code title="schema raw\_telematics\_data" expandable="true" %}

```sql
Tabela 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)}

}

  

Tabela 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)}

}

  

Tabela 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 %}

### Tabelas-chave por categoria

Cada tabela serve a um propósito específico na captura de diferentes aspectos da informação do dispositivo:

<details>

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

**Propósito**: Dados centrais de localização e movimento

<table><thead><tr><th width="181.20001220703125">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Indexação</strong></td><td>Otimizado com índice em (<code>device_id</code>, <code>device_time</code>)</td></tr><tr><td><strong>Notas especiais</strong></td><td>Dados de localização (latitude e longitude) usam formato inteiro com precisão de 10⁷ para desempenho ideal no TimescaleDB<br><br>A velocidade também é armazenada em inteiro, portanto é necessário dividi-la por 100</td></tr></tbody></table>

</details>

<details>

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

**Propósito**: Leituras de sensores dos dispositivos

<table><thead><tr><th width="182">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Conteúdo</strong></td><td>Leituras analógicas (nível de combustível, temperatura, tensão), valores calculados (RPM do motor)</td></tr><tr><td><strong>Relacionamentos</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>

**Propósito**: Indicadores de status do dispositivo e modos operacionais

<table><thead><tr><th width="174.800048828125">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos principais</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>Conteúdo</strong></td><td>Indicadores de modo de operação (trabalhando, inativo, desligado), status de componentes (ignição, portas)</td></tr><tr><td><strong>Formato do valor</strong></td><td>Valores Booleanos (1/0) ou códigos de status específicos</td></tr></tbody></table>

</details>

Os dados neste esquema são ingeridos diretamente dos dispositivos, com latência mínima (tipicamente segundos). O esquema é otimizado para dados de séries temporais usando TimescaleDB para armazenamento e recuperação eficientes.

## Informações adicionais

### Validação de dados

O banco de dados aplica integridade dos dados por meio de vários mecanismos:

* **Restrições CHECK** validam que os valores estejam dentro de intervalos aceitáveis
* **Chaves estrangeiras** asseguram que os relacionamentos entre tabelas permaneçam consistentes
* **Restrições NOT NULL** garantem que campos obrigatórios sempre tenham valores
* **Valores DEFAULT** fornecem um valor de fallback quando os dados não são fornecidos explicitamente

### Otimização de consultas

As tabelas são organizadas com estratégias específicas de indexação:

* Todas as tabelas incluem **índices baseados em tempo** em `record_added_at`
* Colunas de chave estrangeira têm índices dedicados para desempenho em joins
* Combinações de colunas usadas com frequência possuem **índices compostos**
* TimescaleDB fornece índices especializados para consultas de séries temporais

## `repo` estrutura de dados

{% hint style="warning" %}
**Este esquema está atualmente em desenvolvimento.** Se tiver interesse em acesso antecipado ou perguntas sobre essa funcionalidade, por favor contate <iotquery@navixy.com>.
{% endhint %}

O `repo` schema fornece um framework abrangente para gerenciar estruturas organizacionais, ativos, dispositivos e seus relacionamentos em ambientes multi-tenant. Construído sobre PostgreSQL 14+ com a extensão ltree, o esquema suporta organizações hierárquicas, definições de campos personalizados para qualquer tipo de entidade, controle de acesso baseado em função com restrições a nível de objeto e trilhas completas de auditoria com rastreamento de alterações a nível de campo. Todas as entidades podem ser estendidas sem modificações no esquema, localizadas para implantações internacionais e vinculadas por meio de relacionamentos polimórficos flexíveis.

O esquema atende cenários complexos de gerenciamento de dados incluindo hierarquias de ativos de frota através de níveis organizacionais, plataformas SaaS multi-tenant que exigem isolamento de dados, operações orientadas por conformidade com requisitos detalhados de auditoria e sistemas que necessitam de modelos de dados dinâmicos adaptáveis por meio de campos personalizados em vez de migrações de banco de dados.

<figure><img src="https://38152389-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoFNFEIINiGFbhi3Px3dE%2Fuploads%2FOiyhgXkaS0x3wzKquynf%2FNavixy%20Repo%20data%20schema.svg?alt=media&#x26;token=b3148ca9-9b38-4d7a-b246-01d9bc718ae2" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
O diagrama interativo de`repo` o esquema de dados está disponível em **dbdiagram.io**: <https://dbdiagram.io/d/Navixy-Repo-data-schema-68ad788c1e7a611967a0930e>
{% endhint %}

Encontre os `repo` detalhes do esquema abaixo.

{% code title="repo data schema" expandable="true" %}

```sql
// ============================================
// Novo DataHub Schema - Jornada do Cliente
// PostgreSQL 14+ com extensão ltree
// Versão: 2.0 (Conceito)
// ============================================

// ============================================
// TABELAS DE REFERÊNCIA BASE (hierarquia 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
}

// ============================================
// ENTIDADE BASE COM SUPORTE A CAMPOS PERSONALIZADOS
// ============================================

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']
  }
}

// ============================================
// ENTIDADES PRINCIPAIS DE NEGÓCIO
// ============================================

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']
  }
}

// ============================================
// CONTROLE DE ACESSO (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']
  }
}

// ============================================
// ENTIDADES DE NEGÓCIO
// ============================================

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']
  }
}

// ============================================
// LOCALIZAÇÃO
// ============================================

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']
  }
}

// ============================================
// CAMPOS PERSONALIZADOS - DEFINIÇÕES
// ============================================

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']
  }
}

// ============================================
// CAMPOS PERSONALIZADOS - VALORES (por tipo)
// ============================================

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']
  }
}

// ============================================
// AUDITORIA
// ============================================

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']
  }
}

// ============================================
// RELACIONAMENTOS
// ============================================

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 %}

### Frequência de atualização

Os dados no `repo` esquema são sincronizados em tempo real com os sistemas de origem. As atualizações ocorrem imediatamente conforme as mudanças acontecem, com trilhas de auditoria capturando todas as modificações para conformidade e análise histórica.

### `ci_base`

O `repo` esquema usa um padrão Single Table Inheritance para todos os dados de referência por meio do `ci_base` tabela:

O `repo` esquema usa um **Single Table Inheritance** padrão para todos os dados de referência por meio do `ci_base` tabela. Este design consolida dicionários do sistema, classificações e itens de referência definidos pelo usuário em uma estrutura unificada, oferecendo consistência e flexibilidade em todo o esquema.

**Arquitetura:**

O `ci_base` tabela serve como base para todos os dados de referência, usando um `discriminator` campo para identificar o tipo de referência específico. Cada tipo de referência tem uma tabela correspondente (como `ci_device_type`, `ci_asset_type`) que compartilha o mesmo `id` como `ci_base`, criando uma relação de herança segura por tipo.

**Como as entidades de negócio se conectam ao ci\_base:**

Todas as entidades de negócio no `repo` esquema referenciam `ci_base` subtipos para definir sua classificação e comportamento:

* `organization` → referencia `ci_organization_type` (que herda de `ci_entity_type` → `ci_base`)
* `user` → referencia `ci_user_type` (que herda de `ci_entity_type` → `ci_base`)
* `device` → referencia `ci_device_type` e `ci_device_status` (ambos herdam de `ci_base`)
* `asset` → referencia `ci_asset_type` (que herda de `ci_entity_type` → `ci_base`)
* `inventory` → referencia `ci_inventory_type` (que herda de `ci_entity_type` → `ci_base`)
* `asset_group` → referencia `ci_asset_group_type` (que herda de `ci_entity_type` → `ci_base`)

**Categorias de tipo de referência:**

| Categoria                          | Tabelas                                                                                                                                 | Propósito                                                                                  |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **Configuração do sistema**        | `ci_module`, `ci_country`, `ci_role`                                                                                                    | Defina módulos do sistema, referências geográficas e funções de usuário                    |
| **Definições de tipo de entidade** | `ci_entity_type`, `ci_device_type`, `ci_asset_type`, `ci_inventory_type`, `ci_organization_type`, `ci_user_type`, `ci_asset_group_type` | Classificar todas as entidades de negócio por tipo                                         |
| **Status e classificação**         | `ci_device_status`, `ci_asset_type_category`                                                                                            | Acompanhar estados de entidade e agrupar tipos em categorias                               |
| **Controle de acesso**             | `ci_permission_scope`                                                                                                                   | Definir quais permissões podem ser concedidas (conectado a `ci_module` e `ci_entity_type`) |
| **Relacionamentos**                | `ci_device_relation_type`                                                                                                               | Definir tipos de relacionamento entre dispositivos (master-slave, backup, etc.)            |
| **Categorização**                  | `ci_tag`, `ci_catalog_category`                                                                                                         | Habilitar marcação flexível e organização de catálogo                                      |

<details>

<summary><strong>Padrões de consulta de exemplo</strong></summary>

```sql
-- Obter todos os tipos de dispositivo para uma organização (sistema + personalizado)
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;

-- Obter tipo de ativo com sua categoria
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;

-- Obter estrutura hierárquica de tags
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>

### Tabelas-chave por categoria

As tabelas no `repo` os schemas são organizados em categorias funcionais. As descrições abaixo resumem as tabelas mais importantes segundo seu propósito de negócio.

<details>

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

**Propósito:** Gerenciamento de organização hierárquica

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Indexação</strong></td><td>Índice GiST em <code>path</code> para consultas hierárquicas, índices em <code>parent_id</code> e <code>organization_type_id</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Usa ltree para hierarquias multinível, herda de <code>customizable_entity</code> para suporte a campos personalizados</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Contas de usuário e autenticação

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Indexação</strong></td><td>Índice único em (<code>organization_id</code>, <code>identity_provider</code>, <code>identity_provider_id</code>)</td></tr><tr><td><strong>Notas especiais</strong></td><td>Integração com provedores de identidade externos (Keycloak, Auth0, Okta), herda de <code>customizable_entity</code></td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Dispositivos físicos de rastreamento

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Indexação</strong></td><td>Índices em <code>organization_id</code>, <code>device_type_id</code>, <code>status_id</code>, <code>hw_id</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Identificador de hardware para rastreamento de dispositivo, herda de <code>customizable_entity</code> para campos personalizados</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Ativos físicos ou virtuais

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Indexação</strong></td><td>Índices em <code>organization_id</code> e <code>asset_type_id</code></td></tr><tr><td><strong>Notas especiais</strong></td><td>Herda de <code>customizable_entity</code>, vinculado a dispositivos via <code>device_asset_link</code></td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Registros de inventário e armazém

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</strong></td><td><code>id</code>, <code>organization_id</code>, <code>inventory_type_id</code>, <code>code</code></td></tr><tr><td><strong>Indexação</strong></td><td>Índice único em (<code>organization_id</code>, <code>code</code>)</td></tr><tr><td><strong>Notas especiais</strong></td><td>Códigos únicos dentro da organização, vinculados a dispositivos via <code>device_inventory_link</code></td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Agrupamento de ativos com histórico

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Relacionamentos</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>Notas especiais</strong></td><td>Membros baseados em tempo via <code>asset_group_item</code>, consultar membros atuais com <code>WHERE detached_at IS NULL</code></td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Definições de campo personalizado e metadados

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Conteúdo</strong></td><td>Tipos de campo incluem text, number, boolean, date, datetime, entity_ref, catalog_item_ref</td></tr><tr><td><strong>Notas especiais</strong></td><td>Permite campos personalizados flexíveis para qualquer tipo de entidade, valores armazenados em tabelas específicas por tipo <code>custom_field_value_*</code> tabelas</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Gerenciamento de permissões baseado em função

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Conteúdo</strong></td><td>Máscara de ação (READ=1, UPDATE=2, DELETE=4, CREATE=8), permissões específicas por alvo ou por tipo de entidade</td></tr><tr><td><strong>Relacionamentos</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>Notas especiais</strong></td><td>Funciona com <code>user_role</code> e <code>acl_user_scope</code> para determinar permissões finais do usuário</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Registro unificado de auditoria para todas as mudanças do sistema

<table><thead><tr><th width="139">Atributo</th><th>Detalhes</th></tr></thead><tbody><tr><td><strong>Campos-chave</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>Indexação</strong></td><td>Índices em (<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>Notas especiais</strong></td><td>Particionado por <code>occurred_at</code> (mensal), duas categorias: <code>auth</code> (autenticação) e <code>domain</code> (eventos de negócio), armazena deltas de alteração ao nível de campo em <code>event_data</code> JSONB</td></tr></tbody></table>

</details>

### Relacionamentos de dados

O `repo` o schema implementa padrões de relacionamento sofisticados para modelagem de dados flexível:

**Estruturas hierárquicas**

* Organizações usam caminhos ltree para consultas de árvore eficientes
* Itens de referência (`ci_base`) suportam hierarquias opcionais
* Manutenção automática de path via triggers do banco de dados

**Padrões de herança**

* Herança de tabela: `customizable_entity` → entidades de negócio (`organization`, `user`, `device`, `asset`, `inventory`, `asset_group`)
* Herança de ID: `ci_base` → tabelas de tipo de referência
* Discriminação de tipo via `entity_type_id` e `discriminator` campos

**Relacionamentos polimórficos**

Certas tabelas usam referências polimórficas sem restrições de chave estrangeira para máxima flexibilidade:

* `acl_role_permission.target_entity_id` → qualquer `customizable_entity`
* `acl_user_scope.target_entity_id` → qualquer `customizable_entity`
* `entity_tag.entity_id` → qualquer `customizable_entity`

Esses relacionamentos são validados no nível da aplicação.

### Informações adicionais

#### Validação de dados

O `repo` o schema aplica integridade de dados através de múltiplos mecanismos:

**Restrições do banco de dados**

* Restrições UNIQUE com suporte a exclusão suave (índices parciais WHERE `deleted_at` IS NULL)
* Restrições CHECK (por exemplo, `device_relation` garante `master_id` ≠ `slave_id`)
* Restrições NOT NULL em campos obrigatórios
* Valores DEFAULT para timestamps e flags booleanos

**Validação no nível da aplicação**

* Validação de tipo de entidade para referências polimórficas
* Validação de catálogo para referências de campo personalizado
* Validação de tipo de campo personalizado
* Gerenciamento de arrays para campos multi-valor

#### Otimização de consultas

As tabelas são organizadas com estratégias específicas de indexação:

**Índices padrão:**

* Todas as chaves estrangeiras têm índices dedicados
* Índices baseados em tempo em `created_at`, `updated_at`, `deleted_at`
* Índices compostos para colunas frequentemente unidas

**Índices especializados:**

* Índices GiST em caminhos ltree para consultas hierárquicas
* Índices únicos parciais suportando exclusão suave
* Índices de valor de campo personalizado para filtragem e ordenação
* Índices de evento de auditoria por tempo + entidade para pesquisas eficientes

**Considerações de desempenho:**

* Pool de conexões recomendado (PgBouncer)
* Manutenção regular VACUUM para tabelas grandes
* Possível particionamento futuro para `device` tabela por `organization_id`
* Views materializadas para cálculos complexos de controle de acesso
