# Capa de datos brutos

La capa de datos en bruto contiene 3 esquemas de datos distintos, cada uno al servicio de diferentes aspectos de la plataforma de telemática e inteligencia empresarial:

* [`raw_business_data`](#raw_business_data-structure) - que contiene tablas, atributos y valores relacionados con la información empresarial, como vehículos, empleados, geocercas añadidas por los usuarios, etc.
* [`raw_telematics_data`](#raw_telematics_data-structure) - que contiene tablas, atributos y valores relacionados con los datos telemáticos transmitidos desde los dispositivos bajo supervisión, como ubicaciones, entradas, salidas y eventos.
* [`repo`](#repo-data-structure) - que contiene tablas para la gestión de activos e inventario, incluidos tipos de activos configurables, campos personalizados, relaciones entre activos y datos geoespaciales para el seguimiento de recursos organizativos.

Cada esquema está optimizado para su dominio de datos y patrones de acceso específicos, proporcionando una cobertura integral de las necesidades operativas, telemáticas y de gestión de activos.

## `raw_business_data` Estructura

Este esquema contiene más de 40 tablas cuidadosamente seleccionadas para cubrir diversos aspectos empresariales y casos de uso. Estas tablas representan sus entidades empresariales principales, la estructura organizativa y los datos operativos.

<figure><img src="/files/71e245dd942f8cf68554c95804bf119c848e351e" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
El diagrama interactivo del esquema raw\_business\_data está disponible en **dbdiagram.io**: <https://dbdiagram.io/d/V3-bronze-layer-68ecfd1c2e68d21b4131089a>
{% endhint %}

A continuación encontrará los detalles del esquema de datos empresariales en bruto.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

```

{% endcode %}

### Frecuencia de actualización

Los datos de este esquema se sincronizan con la base de datos principal. Las actualizaciones se producen de forma incremental a medida que se producen cambios en la base de datos MySQL de origen, normalmente en menos de 5 minutos desde el cambio de origen.

### `description_parameters`

El sistema incluye datos de referencia para estandarizar valores en toda la base de datos:

<table><thead><tr><th width="167.1817626953125">Tipo de referencia</th><th width="173.9090576171875">Descripción</th><th>Valores de ejemplo</th></tr></thead><tbody><tr><td>Definiciones de tipos</td><td>Tipos de entidad estándar</td><td><code>vehicle_type: car, truck, bus</code></td></tr><tr><td>Códigos de estado</td><td>Valores de estado de tareas y del sistema</td><td><code>tasks_status: unassigned, assigned, done</code></td></tr><tr><td>Definiciones de unidades</td><td>Unidades de medida para sensores</td><td><code>units_type: liter, gallon, celsius</code></td></tr><tr><td>Clasificaciones de entidades</td><td>Categorías de entidades de negocio</td><td><code>entities_type: place, task, customer</code></td></tr></tbody></table>

### Tablas clave por categoría

Las tablas de **`raw_business_data`** schema se organizan en categorías funcionales para facilitar la navegación. La siguiente tabla resume las tablas clave por su finalidad de negocio:

Entidades centrales del negocio

<details>

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

**Descripción**: Cuentas de usuario que contienen información de perfil, afiliación a la empresa, configuración de localización (zona horaria, locale) y relaciones jerárquicas mediante master\_id para estructuras de cuentas multinivel

<table><thead><tr><th width="145">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>user_id</code> - Identificador único del usuario<br>- <code>company_label</code> - Nombre de la empresa asociada al usuario<br>- <code>first_name</code> - Nombre de usuario<br>- <code>last_name</code> - Apellido del usuario<br>- <code>middle_name</code> - Segundo nombre del usuario<br>- <code>locale</code> - Configuración de idioma del usuario<br>- <code>timezone_label</code> - Zona horaria en formato IANA<br>- <code>master_id</code> - ID del usuario principal (si el actual es subordinado)<br>- <code>registration_datetime</code> - Fecha de registro en el sistema<br>- <code>birth_date</code> - Fecha de nacimiento del usuario</td></tr><tr><td><strong>Relaciones</strong></td><td>Usuario principal a través de <code>master_id</code>, vinculado con <code>employees</code>, <code>departments</code>, <code>places</code>, <code>tasks</code> mediante <code>user_id</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Entidad central que conecta los datos organizativos; <code>master_id</code> permite jerarquías de usuarios para estructuras de cuentas multinivel</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Registros de empleados y conductores utilizados para representar a las personas que trabajan para la organización, incluida información personal, datos de licencias, asignaciones a departamentos, llaves de hardware para identificación iButton/RFID y datos de ubicación con soporte de geocercas

<table><thead><tr><th width="143">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>employee_id</code> - Identificador de la entidad empleado<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>department_id</code> - ID del departamento al que se asigna el empleado<br>- <code>first_name</code> - Atributo first_name de la tabla employees<br>- <code>last_name</code> - Atributo last_name de la tabla employees<br>- <code>middle_name</code> - Atributo middle_name de la tabla employees<br>- <code>driver_license_number</code> - Número de licencia de conducir<br>- <code>driver_license_categories</code> - Categorías de la licencia de conducir<br>- <code>driver_license_issue_date</code> - Fecha de emisión de la licencia de conducir<br>- <code>driver_license_valid_till</code> - Fecha hasta la que es válida la licencia de conducir<br>- <code>hardware_key</code> - Una llave de hardware<br>- <code>email</code> - Correo electrónico del empleado<br>- <code>phone_number</code> - Teléfono del empleado sin el signo "+"<br>- <code>address</code> - Dirección de la ubicación<br>- <code>personnel_number</code> - Número de personal del empleado/conductor<br>- <code>citizen_id_number</code> - Número de la Seguridad Social<br>- <code>latitude</code> - Ubicación asociada con este empleado<br>- <code>longitude</code> - Ubicación asociada con este empleado<br>- <code>radius</code> - Ubicación asociada con este empleado en metros<br>- <code>fuel_consumption</code> - Atributo fuel_consumption de la tabla employees<br>- <code>fuel_cost</code> - Atributo fuel_cost de la tabla employees<br>- <code>is_deleted</code> - Atributo is_deleted de la tabla employees</td></tr><tr><td><strong>Relaciones</strong></td><td>Enlaces a <code>users</code>, <code>departments</code>, <code>objetos</code> (rastreador asignado), rastreado en <code>driver_history</code> y <code>checkins</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>La llave de hardware permite la identificación del conductor mediante iButton o RFID; admite geocercas con <code>latitude</code>, <code>longitude</code>, <code>radius</code> campos</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Unidades organizativas con datos de ubicación geográfica (latitud, longitud, radio) que permiten análisis basados en geocercas para informes a nivel de departamento y asociación de ubicación del empleado

<table><thead><tr><th width="156">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>department_id</code> - Identificador de la entidad departamento<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>department_label</code> - Atributo department_label de la tabla departments<br>- <code>latitude</code> - Ubicación asociada con este departamento<br>- <code>longitude</code> - Ubicación asociada con este departamento<br>- <code>radius</code> - Tamaño de geolocalización en metros<br>- <code>address</code> - Atributo address de la tabla departments</td></tr><tr><td><strong>Relaciones</strong></td><td>Vincula a los empleados con la estructura organizativa mediante <code>department_id</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Los campos de ubicación permiten análisis basados en geocercas para informes a nivel de departamento</td></tr></tbody></table>

</details>

Seguimiento y monitorización

<details>

<summary><strong><code>dispositivos</code></strong></summary>

**Descripción**: Registro de dispositivos físicos de seguimiento con identificadores de hardware (IMEI), información de tarjeta SIM, estado de conectividad de red (intensidad de señal, roaming, operador) y asignaciones de listas de estado para la gestión del ciclo de vida del dispositivo

<table><thead><tr><th width="138">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>device_id</code> - ID del dispositivo<br>- <code>owner_id</code> - ID del propietario del dispositivo en cuya cuenta se agregó el beacon<br>- <code>device_imei</code> - IMEI del dispositivo<br>- <code>phone</code> - Número de la tarjeta SIM del dispositivo<br>- <code>status_listing_id</code> - ID de estado del dispositivo<br>- <code>network_label</code> - Nombre de la red a la que está conectada la tarjeta SIM<br>- <code>signal_level</code> - Intensidad de la señal del dispositivo<br>- <code>has_roaming</code> - Indicador de disponibilidad de roaming<br>- <code>is_sim_blocked</code> - Indicador de bloqueo de la tarjeta SIM<br>- <code>created_at</code> - Fecha y hora en que se creó la entrada</td></tr><tr><td><strong>Relaciones</strong></td><td>Entidad central que enlaza con <code>objetos</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 especiales</strong></td><td>Todos los datos telemáticos en <code>raw_telematics_data</code> schema hacen referencia a esta tabla mediante <code>device_id</code></td></tr></tbody></table>

</details>

<details>

<summary><strong><code>objetos</code></strong></summary>

**Descripción**: Registro central de entidades monitorizadas (vehículos, activos, personal) que vincula dispositivos físicos con la estructura organizativa mediante client\_id y group\_id, representando la "unidad rastreable" con un objeto activo por dispositivo

<table><thead><tr><th width="148">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>client_id</code> - Identificador de la entidad cliente<br>- <code>device_id</code> - Identificador de la entidad dispositivo<br>- <code>object_label</code> - Nombre del objeto<br>- <code>model</code> - Modelo del dispositivo<br>- <code>group_id</code> - Grupo de ID de entidad<br>- <code>create_datetime</code> - Fecha y hora de creación de una nueva fila en el servidor<br>- <code>is_deleted</code> - Atributo is_deleted de la tabla objects<br>- <code>is_clone</code> - Indicador de clon</td></tr><tr><td><strong>Relaciones</strong></td><td>Centro principal que conecta los dispositivos con los usuarios (<code>client_id</code>), los detalles del vehículo, el historial de seguimiento, las tareas y las reglas</td></tr><tr><td><strong>Notas especiales</strong></td><td>Representa la "unidad rastreable" en el sistema; un objeto por dispositivo en uso activo</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Registro central de entidades monitorizadas (vehículos, activos, personal) que vincula dispositivos físicos con la estructura organizativa mediante client\_id y group\_id, representando la "unidad rastreable" con un objeto activo por dispositivo

<table><thead><tr><th width="135">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>model_id</code> - Identificador del modelo de la entidad<br>- <code>model</code> - Atributo model de la tabla models<br>- <code>vendor</code> - Nombre de la empresa que lanzó el rastreador<br>- <code>alternative_label</code> - Atributo alternative_label de la tabla models<br>- <code>analog_amount</code> - Número de entradas analógicas del rastreador<br>- <code>digital_amount</code> - Número de entradas discretas del rastreador<br>- <code>outputs_amount</code> - Número de salidas discretas del rastreador<br>- <code>has_battery_level</code> - Determina si el rastreador transmite lecturas del nivel de batería<br>- <code>has_altitude</code> - Determina si el rastreador transmite altitud<br>- <code>has_phone</code> - ¿Hay una tarjeta SIM?<br>- <code>has_gsm_level</code> - ¿Puede un rastreador transmitir la intensidad de la señal GSM?<br>- <code>has_gsm_name</code> - ¿Puede el rastreador transmitir el nombre de la red GSM o el código del operador (MCC + MNC)?<br>- <code>has_gsm_roaming</code> - ¿Puede el rastreador transmitir el estado de roaming?<br>- <code>has_detach_button</code> - ¿Tiene el rastreador un sensor de desconexión?<br>- <code>type_output_control</code> - Perfil de control de salidas del rastreador<br>- <code>type_special_control</code> - Contiene configuraciones especializadas y módulos funcionales para modelos de dispositivos individuales, como el modo de conducción peligrosa (hbm_telfm) para equipos Teltonika<br>- <code>is_clone</code> - ¿El modelo es una clonación de otro modelo?</td></tr><tr><td><strong>Contenido</strong></td><td>Los indicadores booleanos de capacidad indican qué campos de datos están disponibles para este tipo de dispositivo</td></tr><tr><td><strong>Notas especiales</strong></td><td>Utilice los indicadores de capacidad para determinar sensores y entradas válidos al consultar datos telemáticos</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Configuración integral de sensores que vincula las entradas del dispositivo con la lógica de negocio, incluyendo asignaciones de entrada, unidades de medida, factores de conversión (multiplicador/divisor), tablas de calibración para sensores de combustible, umbrales de precisión y lógica de agrupación para lecturas de sensores agregadas

<table><thead><tr><th width="142">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>sensor_id</code> - Identificador de la entidad sensor<br>- <code>device_id</code> - Identificador de la entidad dispositivo<br>- <code>sensor_label</code> - Nombre del sensor para la interfaz de usuario<br>- <code>input_label</code> - Nombre del campo del mensaje (atributo) del que se toman los datos del sensor. Si es igual a "input_status", se trata de un sensor discreto<br>- <code>sensor_type</code> - Tipo de sensor<br>- <code>units_type</code> - Unidades de medida<br>- <code>multiplier</code> - Multiplicador: número por el que se multiplica el valor del campo. Solo para sensores de medición<br>- <code>divider</code> - Divisor: número por el que se divide el valor del campo. Solo para sensores de medición<br>- <code>accuracy</code> - Porcentaje especificado para calcular el error absoluto del volumen del tanque. Este error se utiliza para determinar cuándo se están produciendo repostajes o descargas. Solo se utiliza para sensores de combustible<br>- <code>calibration_data</code> - Atributo calibration_data de la tabla sensor_description<br>- <code>input_id</code> - Número de entrada para sensor discreto<br>- <code>group_id</code> - Los sensores del mismo tipo con el mismo group_id y source_id se consideran pertenecientes al mismo grupo. Sus datos se suman o promedian, según el valor de group_type. Esto es necesario para sensores agregados. Se utiliza en sensores de medición<br>- <code>group_type</code> - 0 - suma los valores de los sensores dentro de un grupo, 1 - promedio<br>- <code>sensor_units</code> - Nombre de la unidad introducido por el usuario si units_type=0 (personalizado)<br>- <code>parameters</code> - Objeto opcional con parámetros adicionales parent_ids - array opcional de parent_ids para sensor compuesto. volume - double. Volumen opcional para sensor compuesto. parent_ids - opcional. Array int. Array de parent_ids para sensor compuesto. volume - opcional. Double. Volumen para sensor compuesto. min - opcional. Double. Valor bruto mínimo aceptable para un sensor. max - opcional. Double. Valor bruto máximo aceptable para un sensor. max_lowering_by_time - opcional. Double. Máxima disminución legal del valor por hora. max_lowering_by_mileage - opcional. Double. Máxima disminución legal del valor por cada 100 km. ignore_drains_in_move - opcional. Boolean. El valor predeterminado es false. Si es true, los drenajes de combustible no se detectarán durante el movimiento. ignore_refuels_in_move - opcional. Boolean. El valor predeterminado es false. Si es true, los repostajes no se detectarán durante el movimiento. refuel_gap_minutes - opcional. Integer. El valor predeterminado es 5. El tiempo en minutos después del inicio del movimiento, los repostajes se detectarán durante el movimiento. custom_field_name - opcional. Boolean. El valor predeterminado es false. El parámetro determina si el campo input_name es un valor personalizado introducido por el usuario. Esto solo tiene sentido si el modelo del rastreador tiene la función has_custom_fields</td></tr><tr><td><strong>Relaciones</strong></td><td>Vincula las entradas del dispositivo (desde <code>raw_telematics_data.inputs</code>) con la lógica de negocio mediante <code>device_id</code> y <code>input_label</code> matching</td></tr><tr><td><strong>Notas especiales</strong></td><td><code>calibration_data</code> (JSONB) almacena tablas de calibración específicas del sensor para sensores de nivel de combustible; <code>multiplier</code> y <code>divider</code> convierte los valores brutos en unidades</td></tr></tbody></table>

</details>

Gestión de activos

<details>

<summary><strong><code>vehículos</code></strong></summary>

**Descripción**: Registro integral de vehículos que contiene especificaciones (dimensiones, peso, capacidad), documentación (VIN, registro, seguro), parámetros operativos (consumo de combustible, volumen del depósito) y la asignación actual del rastreador mediante object\_id para la gestión de flotas y el seguimiento del cumplimiento

<table><thead><tr><th width="144">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>vehicle_id</code> - Identificador de la entidad vehículo<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>garage_id</code> - Identificador de la entidad garaje<br>- <code>vehicle_label</code> - Atributo vehicle_label de la tabla vehicles<br>- <code>registration_number</code> - Número de registro/matrícula de un vehículo<br>- <code>vin</code> - Atributo vin de la tabla vehicles<br>- <code>manufacture_year</code> - Atributo manufacture_year de la tabla vehicles<br>- <code>fuel_type</code> - Atributo fuel_type de la tabla vehicles<br>- <code>fuel_cost</code> - Atributo fuel_cost de la tabla vehicles<br>- <code>fuel_tank_volume</code> - Atributo fuel_tank_volume de la tabla vehicles<br>- <code>max_speed</code> - Atributo max_speed de la tabla vehicles<br>- <code>model</code> - Atributo model de la tabla vehicles<br>- <code>color</code> - Atributo color de la tabla vehicles<br>- <code>trailer</code> - Atributo trailer de la tabla vehicles<br>- <code>additional_info</code> - Atributo additional_info de la tabla vehicles<br>- <code>vehicle_type</code> - Atributo vehicle_type de la tabla vehicles<br>- <code>vehicle_subtype</code> - Atributo vehicle_subtype de la tabla vehicles<br>- <code>vehicle_status_id</code> - Identificador de la entidad estado del vehículo<br>- <code>chassis_number</code> - Atributo chassis_number de la tabla vehicles<br>- <code>frame_number</code> - Atributo frame_number de la tabla vehicles<br>- <code>trailer_reg_number</code> - Atributo trailer_reg_number de la tabla vehicles<br>- <code>payload_weight</code> - Atributo payload_weight de la tabla vehicles<br>- <code>payload_height</code> - Atributo payload_height de la tabla vehicles<br>- <code>payload_length</code> - Atributo payload_length de la tabla vehicles<br>- <code>payload_width</code> - Atributo payload_width de la tabla vehicles<br>- <code>passenger_capacity</code> - Número máximo de pasajeros<br>- <code>gross_weight</code> - Atributo gross_weight de la tabla vehicles<br>- <code>standard_fuel_consumption</code> - Consumo medio normal de combustible en litros por 100 km<br>- <code>fuel_grade</code> - Atributo fuel_grade de la tabla vehicles<br>- <code>wheel_arrangement</code> - Atributo wheel_arrangement de la tabla vehicles<br>- <code>tyre_size</code> - Tamaño del vehículo: dimensiones y tamaño de las ruedas<br>- <code>tyres_number</code> - Número de ruedas<br>- <code>liability_insurance_policy_number</code> - Atributo liability_insurance_policy_number de la tabla vehicles<br>- <code>liability_insurance_valid_till</code> - Fecha hasta la que es válida la cobertura de responsabilidad civil<br>- <code>free_insurance_policy_number</code> - Atributo free_insurance_policy_number de la tabla vehicles<br>- <code>free_insurance_valid_till_date</code> - Fecha hasta la que es válida el seguro gratuito</td></tr><tr><td><strong>Relaciones</strong></td><td>Enlaces a <code>objetos</code> (rastreador actual), <code>garages</code> (ubicación de servicio), <code>vehicle_service_tasks</code>; rastreado en <code>vehicle_trackers_history</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Los campos de dimensiones físicas (<code>payload_length</code>, <code>payload_width</code>, <code>payload_height</code>, <code>gross_weight</code>) admiten análisis de planificación de cargas; las fechas del seguro permiten el seguimiento del cumplimiento</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Ubicaciones de centros de servicio y mantenimiento con coordenadas geográficas (latitud, longitud, radio), información de contacto de mecánicos y despachadores, que permiten la detección de visitas de servicio basada en geocercas y el análisis de proximidad

<table><thead><tr><th width="135">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>garage_id</code> - Identificador de la entidad garaje<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>latitude</code> - Objeto de ubicación<br>- <code>longitude</code> - Objeto de ubicación<br>- <code>radius</code> - Tamaño de geolocalización en metros<br>- <code>address</code> - Objeto de ubicación<br>- <code>organization_label</code> - ID del depósito<br>- <code>mechanic_name</code> - Nombre del mecánico<br>- <code>dispatcher_name</code> - Nombre del despachador</td></tr><tr><td><strong>Relaciones</strong></td><td>Referenciado por <code>vehicles.garage_id</code> para la asignación de ubicación de servicio</td></tr><tr><td><strong>Notas especiales</strong></td><td>Los campos de ubicación permiten la detección de visitas de servicio basada en geocercas y el análisis de proximidad</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Seguimiento del programa de mantenimiento y del historial de servicio con múltiples tipos de activación (basado en fecha, basado en kilometraje, basado en horas de motor), intervalos de tareas recurrentes, notificaciones multicanal (correo electrónico, SMS, push) y distinción entre eventos de mantenimiento planificados (is\_repeat) y no planificados

<table><thead><tr><th width="132">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>service_task_id</code> - Identificador de la entidad tarea de servicio<br>- <code>vehicle_id</code> - Identificador de la entidad vehículo<br>- <code>description</code> - Atributo description de la tabla vehicle_service_tasks<br>- <code>status</code> - Valor del estado del atributo status<br>- <code>cost</code> - Atributo cost de la tabla vehicle_service_tasks<br>- <code>start_date</code> - Fecha y hora asociadas al atributo start_date<br>- <code>end_date</code> - Fecha y hora asociadas al atributo end_date<br>- <code>completion_date</code> - Fecha y hora asociadas al atributo completion_date<br>- <code>predicted_datetime</code> - Fecha y hora asociadas al atributo predicted_datetime<br>- <code>mileage_limit</code> - Atributo mileage_limit de la tabla vehicle_service_tasks<br>- <code>engine_hours_limit</code> - Atributo engine_hours_limit de la tabla vehicle_service_tasks<br>- <code>start_mileage</code> - Atributo start_mileage de la tabla vehicle_service_tasks<br>- <code>start_engine_hours</code> - Atributo start_engine_hours de la tabla vehicle_service_tasks<br>- <code>mileage_notification_interval</code> - Atributo mileage_notification_interval de la tabla vehicle_service_tasks<br>- <code>engine_hours_notification_interval</code> - Atributo engine_hours_notification_interval de la tabla vehicle_service_tasks<br>- <code>date_notification_interval</code> - Conversión de un entero N en N días<br>- <code>mileage_repeat_interval</code> - Atributo mileage_repeat_interval de la tabla vehicle_service_tasks<br>- <code>engine_hours_repeat_interval</code> - Atributo engine_hours_repeat_interval de la tabla vehicle_service_tasks<br>- <code>date_repeat_interval</code> - Conversión de un entero N en N días<br>- <code>notification_emails</code> - Atributo notification_emails de la tabla vehicle_service_tasks<br>- <code>notification_sms_phone_numbers</code> - Atributo notification_sms_phone_numbers de la tabla vehicle_service_tasks<br>- <code>is_notification_push_enabled</code> - Atributo is_notification_push_enabled de la tabla vehicle_service_tasks<br>- <code>completion_mileage</code> - Atributo completion_mileage de la tabla vehicle_service_tasks<br>- <code>completion_engine_hours</code> - Atributo completion_engine_hours de la tabla vehicle_service_tasks<br>- <code>is_repeat</code> - Atributo is_repeat de la tabla vehicle_service_tasks<br>- <code>is_unplanned</code> - Atributo is_unplanned de la tabla vehicle_service_tasks<br>- <code>comment</code> - Atributo comment de la tabla vehicle_service_tasks</td></tr><tr><td><strong>Contenido</strong></td><td>Admite tres tipos de activación: basado en fecha, basado en kilometraje, basado en horas de motor; configuraciones de notificación para correo electrónico, SMS, push</td></tr><tr><td><strong>Notas especiales</strong></td><td><code>is_repeat</code> y los campos de intervalo permiten programas de mantenimiento recurrentes; <code>is_unplanned</code> distingue entre mantenimiento programado y reactivo</td></tr></tbody></table>

</details>

Ubicación y rutas

<details>

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

**Descripción**: Áreas geocercadas que definen perímetros virtuales mediante círculos o polígonos para supervisar eventos de entrada y salida de vehículos/activos, con automatización basada en reglas y análisis de ubicación con codificación por colores para diferenciación visual

<table><thead><tr><th width="150">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>zone_id</code> - Identificador de la entidad zona<br>- <code>client_id</code> - Identificador de la entidad cliente<br>- <code>zone_label</code> - Atributo zone_label de la tabla zones<br>- <code>zone_type</code> - Atributo zone_type de la tabla zones<br>- <code>latitude</code> - Objeto opcional, el cuadro delimitador que puede contener completamente el resultado devuelto<br>- <code>longitude</code> - Objeto opcional, el cuadro delimitador que puede contener completamente el resultado devuelto<br>- <code>circle_center_latitude</code> - Atributo circle_center_latitude de la tabla zones<br>- <code>circle_center_longitude</code> - Atributo circle_center_longitude de la tabla zones<br>- <code>radius</code> - Tamaño de geolocalización en metros<br>- <code>address</code> - Atributo address de la tabla zones<br>- <code>color</code> - Atributo color de la tabla zones</td></tr><tr><td><strong>Contenido</strong></td><td>Los tipos de zona incluyen círculo, polígono (definido mediante <code>geofence_points</code>), y clasificaciones especiales de áreas</td></tr><tr><td><strong>Relaciones</strong></td><td>Referenciado por <code>rules2zones</code>, <code>users2zones</code>; los vértices del polígono se almacenan en <code>geofence_points</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Las funciones de PostGIS se pueden utilizar para comprobar si un punto está dentro de un polígono para análisis complejos de geocercas</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Puntos de interés con coordenadas geográficas, definiciones de radio y soporte de campos personalizados extensibles para almacenar información de contacto de clientes y datos específicos del negocio, permitiendo la integración con CRM/ERP mediante external\_id e informes basados en la ubicación

<table><thead><tr><th width="129">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>place_id</code> - Identificador de la entidad lugar<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>place_label</code> - Atributo place_label de la tabla places<br>- <code>latitude</code> - Objeto de ubicación<br>- <code>longitude</code> - Objeto de ubicación<br>- <code>radius</code> - Tamaño de geolocalización en metros<br>- <code>address</code> - Atributo address de la tabla places<br>- <code>description</code> - Atributo description de la tabla places<br>- <code>external_id</code> - ID para integración con sistemas externos (CRM)<br>- <code>custom_fields</code> - Campos adicionales<br>- <code>assigned_datetime</code> - Fecha y hora de asignación del punto de interés al usuario</td></tr><tr><td><strong>Relaciones</strong></td><td>Ampliado con valores de campos personalizados mediante <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 especiales</strong></td><td><code>custom_fields</code> JSONB proporciona acceso rápido; las tablas relacionadas permiten filtrar y ordenar por atributos personalizados</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Coordenadas de vértices ordenadas (el campo number determina la secuencia) que definen los límites del polígono para formas complejas de geocerca, lo que permite perímetros geográficos precisos más allá de las simples zonas circulares, utilizado con PostGIS ST\_MakePolygon para operaciones geométricas

<table><thead><tr><th width="133">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>zone_id</code> - Un ID de la zona a la que está vinculado este formulario<br>- <code>number</code> - Número de serie<br>- <code>latitude</code> - Ubicación<br>- <code>longitude</code> - Ubicación</td></tr><tr><td><strong>Relaciones</strong></td><td>Múltiples registros por <code>zone_id</code> definen los límites del polígono; <code>number</code> el campo determina el orden de los vértices</td></tr><tr><td><strong>Notas especiales</strong></td><td>Consultar con <code>ORDER BY number</code> para reconstruir la ruta del polígono; utilícelo con PostGIS ST_MakePolygon para operaciones geométricas</td></tr></tbody></table>

</details>

Gestión de tareas y flujos de trabajo

<details>

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

**Descripción**: Asignaciones de órdenes de trabajo con validación de ubicación (latitude, longitude, radius), ventanas de tiempo (time\_from, time\_to), requisitos de duración de la visita (stay\_duration\_minutes, arrival\_duration\_minutes), estructura jerárquica mediante parent\_task\_id y seguimiento de estado para la gestión de servicios de campo y las operaciones de entrega

<table><thead><tr><th width="130">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>task_id</code> - Identificador de la entidad de tarea<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>parent_task_id</code> - Identificador de la entidad de tarea padre<br>- <code>task_label</code> - El atributo task_label de la tabla tasks<br>- <code>status</code> - Valor del estado del atributo status<br>- <code>task_type</code> - Tipo de tarea, tarea, ruta o punto de control<br>- <code>latitude</code> - El atributo latitude de la tabla tasks<br>- <code>longitude</code> - El atributo longitude de la tabla tasks<br>- <code>radius</code> - Tamaño de geolocalización en metros<br>- <code>arrival_datetime</code> - Cuando el rastreador llega al área de la tarea. SE IGNORA al crear/actualizar<br>- <code>created_at</code> - El atributo created_at de la tabla tasks<br>- <code>status_change_datetime</code> - Fecha y hora de actualización de la tarea<br>- <code>time_from</code> - La fecha y hora asociadas con el atributo time_from<br>- <code>time_to</code> - La fecha y hora asociadas con el atributo time_to<br>- <code>stay_duration</code> - El atributo stay_duration de la tabla tasks<br>- <code>stay_duration_minutes</code> - Duración de la visita. El tiempo que un trabajador móvil debe pasar en el lugar de la asignación para completar con éxito la tarea. Varias visitas son acumulativas<br>- <code>arrival_duration_minutes</code> - Ignorar visitas aleatorias más cortas que la duración especificada. Al calcular la duración mínima, las visitas más cortas que la duración especificada se ignorarán<br>- <code>max_delay_minuts</code> - Retraso permitido. La cantidad máxima de tiempo que un empleado puede llegar tarde. Cualquier tarea completada durante este tiempo se marcará como "tarde"<br>- <code>is_stay_control_enabled</code> - El atributo is_stay_control_enabled de la tabla tasks<br>- <code>address</code> - El atributo address de la tabla tasks<br>- <code>description</code> - El atributo description de la tabla tasks<br>- <code>custom_fields</code> - El atributo custom_fields de la tabla tasks<br>- <code>external_id</code> - Identificador de entidad externa<br>- <code>order_sort</code> - El atributo order_sort de la tabla tasks<br>- <code>created_by</code> - Origen de la tarea creada</td></tr><tr><td><strong>Contenido</strong></td><td>Admite tareas jerárquicas mediante <code>parent_task_id</code>; ventanas de tiempo definidas por <code>time_from</code>/<code>time_to</code>; validación de geocerca con ubicación y radio</td></tr><tr><td><strong>Relaciones</strong></td><td>Enlaces a <code>forms</code> (recopilación de datos), <code>task_history</code> (cambios de estado), <code>objetos</code> (rastreador asignado)</td></tr><tr><td><strong>Notas especiales</strong></td><td><code>stay_duration</code> y <code>arrival_duration_minutes</code> permiten el monitoreo del cumplimiento de las tareas de entrega y servicio</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Formularios configurables de recopilación de datos para capturar información estructurada durante la finalización de tareas o los registros de entrada en la aplicación móvil, con campos y valores almacenados como JSON, validación de ubicación opcional (is\_submission\_in\_zone) y requisitos obligatorios de envío cuando están vinculados a tareas

<table><thead><tr><th width="141">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>form_id</code> - Identificador de la entidad de formulario<br>- <code>task_id</code> - Un ID de la tarea a la que está vinculado este formulario<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>form_label</code> - Etiqueta de formulario definida por el usuario<br>- <code>campos</code> - Si es true, el formulario solo se puede enviar dentro de la zona de la tarea<br>- <code>values</code> - Un mapa con los ID de campo como claves y los objetos field_value como valores. Clave utilizada para vincular el campo y su valor correspondiente<br>- <code>submitted_at</code> - Fecha en que se enviaron por última vez los valores del formulario<br>- <code>submission_latitude</code> - Ubicación en la que se enviaron por última vez los valores del formulario<br>- <code>submission_longitude</code> - Ubicación en la que se enviaron por última vez los valores del formulario<br>- <code>submission_address</code> - Ubicación en la que se enviaron por última vez los valores del formulario<br>- <code>is_submission_in_zone</code> - Si es true, el formulario solo se puede enviar dentro de la zona de la tarea<br>- <code>description</code> - Fecha en que se creó este formulario (o se vinculó a la tarea)<br>- <code>created_at</code> - Fecha en que se creó este formulario (o se vinculó a la tarea)</td></tr><tr><td><strong>Contenido</strong></td><td><code>campos</code> define la estructura del formulario (JSON); <code>values</code> contiene los datos enviados (JSON)</td></tr><tr><td><strong>Relaciones</strong></td><td>Enlaces a <code>tasks</code> (orden de trabajo asociado), <code>objetos</code> (remitente), referenciado en <code>checkins</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Indicador de validación de ubicación <code>is_submission_in_zone</code> habilita reglas de envío de formularios basadas en geocercas</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Registros de asistencia y actividad basados en la ubicación enviados mediante la aplicación móvil, que rastrean los tiempos de llegada planificados frente a los reales (planned\_datetime vs actual\_datetime) con coordenadas geográficas y mediciones de precisión de ubicación (radius) para informes de puntualidad

<table><thead><tr><th width="129">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>checkin_id</code> - Identificador de la entidad de check-in<br>- <code>employee_id</code> - El identificador de la entidad de empleado también es el identificador de los conductores<br>- <code>object_id</code> - Dispositivo del empleado<br>- <code>form_id</code> - Identificador de la entidad de formulario<br>- <code>user_id</code> - Usuario empleado<br>- <code>planned_datetime</code> - Hora del dispositivo cuando se realizó el check-in<br>- <code>actual_datetime</code> - Hora del servidor cuando se procesó la solicitud/mensaje<br>- <code>latitude</code> - Ubicación en la que se enviaron los check-ins<br>- <code>longitude</code> - Ubicación en la que se enviaron los check-ins<br>- <code>radius</code> - Error de posicionamiento en un punto en metros<br>- <code>address</code> - Dirección del check-in<br>- <code>comment</code> - El atributo comment de la tabla checkins</td></tr><tr><td><strong>Relaciones</strong></td><td>Conecta a los empleados con formularios y ubicaciones; hace seguimiento de las desviaciones respecto al horario planificado</td></tr><tr><td><strong>Notas especiales</strong></td><td>Variación temporal entre <code>planned_datetime</code> y <code>actual_datetime</code> permite generar informes de puntualidad; radius define la tolerancia aceptable de ubicación</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Registro de auditoría completo de los eventos del ciclo de vida de las tareas que captura todos los cambios de estado, asignaciones, actualizaciones y modificaciones de campos con marcas de tiempo (event\_datetime), atribución de usuario y tipos de actividad (create, update, assign, status\_change) almacenados en el campo payload para el análisis de cumplimiento y flujo de trabajo

<table><thead><tr><th width="137">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>task_history_id</code> - Identificador de la entidad de historial de tareas<br>- <code>task_id</code> - Identificador de la entidad de tarea<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>activity</code> - Operación que ocurrió. Puede ser "create", "update", "assign" o "status_change"<br>- <code>event_datetime</code> - Fecha y hora del evento<br>- <code>payload</code> - Depende de la operación. Normalmente, contiene los campos que se modificaron durante la operación</td></tr><tr><td><strong>Contenido</strong></td><td>Tipos de actividad definidos en <code>description_parameters</code>; <code>payload</code> almacena detalles específicos del evento (texto)</td></tr><tr><td><strong>Notas especiales</strong></td><td>Esencial para el análisis de finalización de tareas, la elaboración de informes sobre transiciones de estado y el seguimiento de la actividad del usuario</td></tr></tbody></table>

</details>

Reglas y automatización

<details>

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

**Descripción**: Reglas de detección de eventos con condiciones de activación configurables (exceso de velocidad, infracciones de geocerca, umbrales de sensores, tiempo de inactividad) almacenadas en parameters (JSONB), y ajustes de notificación multicanal (alert\_email, alert\_sms, alert\_phone, is\_push\_enabled) para el monitoreo y la alerta automatizados basados en datos del dispositivo y del servidor

<table><thead><tr><th width="131">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>rule_id</code> - Identificador de la entidad de regla<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>client_id</code> - Identificador de la entidad cliente<br>- <code>event_type</code> - El atributo event_type de la tabla rules<br>- <code>event_label</code> - El atributo event_label de la tabla rules<br>- <code>event_group</code> - El atributo event_group de la tabla rules<br>- <code>description</code> - El atributo description de la tabla rules<br>- <code>parameters</code> - Parámetros del evento. Para obtener más detalles sobre los parámetros disponibles, consulte <a href="https://www.navixy.com/docs/navixy-api/user-api/backend-api/resources/tracking/tracker/rules/rule_types/">documentación de la API de Navixy</a>.<br>- <code>alert_email</code> - Correo para notificaciones<br>- <code>alert_sms</code> - Números de teléfono para notificaciones por SMS<br>- <code>alert_phone</code> - Teléfonos para llamadas de voz<br>- <code>is_push_enabled</code> - Si es true, las notificaciones push están disponibles<br>- <code>created_at</code> - El atributo created_at de la tabla rules<br>- <code>is_deleted</code> - El atributo is_deleted de la tabla rules<br>- <code>maximum</code> - Límites aplicados a varias reglas. Por ejemplo, para la regla de tiempo de inactividad con el motor en marcha en minutos<br>- <code>event_comment1</code> - El atributo event_comment1 de la tabla rules<br>- <code>event_comment2</code> - El atributo event_comment2 de la tabla rules</td></tr><tr><td><strong>Contenido</strong></td><td>Los parámetros de la regla (JSONB) definen las condiciones de activación; admite notificaciones por correo electrónico, SMS, teléfono y push</td></tr><tr><td><strong>Relaciones</strong></td><td>Vínculos con objetos mediante <code>rules2objects</code>, zonas mediante <code>rules2zones</code></td></tr><tr><td><strong>Notas especiales</strong></td><td><code>event_type</code> define un escenario de monitoreo específico (exceso de velocidad, infracción de geocerca, umbral de sensor); <code>maximum</code> el campo permite la agregación de eventos para alertas basadas en umbrales</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Relación de muchos a muchos que vincula las reglas con los objetos monitoreados con personalización de parámetros por objeto mediante object\_params (JSONB), lo que permite diferentes valores de umbral (por ejemplo, límites de velocidad) para cada vehículo o activo dentro de la misma regla

<table><thead><tr><th width="140">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>rule_id</code> - Identificador de la entidad de regla<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>param_group_number</code> - El atributo param_group_number de la tabla rules2objects<br>- <code>object_params</code> - El atributo object_params de la tabla rules2objects</td></tr><tr><td><strong>Contenido</strong></td><td><code>object_params</code> (JSONB) permite la personalización de reglas por objeto (por ejemplo, distintos límites de velocidad por vehículo)</td></tr><tr><td><strong>Notas especiales</strong></td><td>La relación de muchos a muchos permite que una regla supervise varios objetos con distintos parámetros</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Relación de muchos a muchos que asocia las reglas con zonas geocercadas, lo que permite que una sola regla supervise eventos de entrada y salida en múltiples áreas geográficas para escenarios complejos de monitoreo espacial

<table><thead><tr><th width="144">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>rule_id</code> - Identificador de la entidad de regla<br>- <code>zone_id</code> - Identificador de la entidad de zona</td></tr><tr><td><strong>Notas especiales</strong></td><td>La relación de muchos a muchos permite el monitoreo de múltiples zonas para una sola regla (por ejemplo, alertar al entrar en cualquiera de varias áreas restringidas)</td></tr></tbody></table>

</details>

Estado y categorización

<details>

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

**Descripción**: Definiciones de estados personalizados dentro de los listados de estados, incluidas las propiedades de visualización (color para la visualización en el sitio web, order\_sort para la posición) utilizadas para representar los estados de trabajo del dispositivo o del empleado con compatibilidad de eliminación suave mediante el indicador is\_deleted

<table><thead><tr><th width="128">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>status_id</code> - Estado del identificador de entidad<br>- <code>listing_id</code> - Identificador de la entidad de lista<br>- <code>status_label</code> - Valor de estado del atributo status_label<br>- <code>color</code> - Color utilizado para la visualización en el sitio web<br>- <code>order_sort</code> - Posición de orden dentro del estado de la lista<br>- <code>is_deleted</code> - El atributo is_deleted de la tabla statuses</td></tr><tr><td><strong>Relaciones</strong></td><td>Grupos de estados organizados por <code>listing_id</code> (referencias <code>status_listings</code>); utilizado en <code>status_history</code></td></tr><tr><td><strong>Notas especiales</strong></td><td><code>order_sort</code> define la secuencia de visualización; el color permite la diferenciación visual en los informes</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Definiciones de conjuntos de estados que controlan qué valores de estado están disponibles para dispositivos o empleados, con indicadores de permiso (is\_supervisor\_controlled, is\_employee\_controlled) que determinan si los supervisores, los empleados o ambos pueden cambiar los valores de estado

<table><thead><tr><th width="144">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>status_listing_id</code> - Identificador de la entidad del listado de estados<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>status_listing_label</code> - Valor de estado del atributo status_listing_label<br>- <code>is_supervisor_controlled</code> - Si es true, los supervisores pueden cambiar el estado de trabajo, por ejemplo, usando la aplicación móvil de monitoreo<br>- <code>is_employee_controlled</code> - Si es true, los empleados pueden cambiar su propio estado de trabajo, por ejemplo, usando la aplicación móvil de rastreo<br>- <code>is_deleted</code> - El atributo is_deleted de la tabla status_listings</td></tr><tr><td><strong>Relaciones</strong></td><td>Referenciado por <code>devices.status_listing_id</code> y <code>statuses.listing_id</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Los indicadores de control determinan quién puede cambiar los estados: solo supervisores, autoservicio de los empleados o ambos</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Registro de auditoría de todas las transiciones de estado del dispositivo con marcas de tiempo (changed\_datetime en el dispositivo, server\_datetime en el servidor), atribución de usuario (updated\_by) y captura de ubicación (latitude, longitude, address), lo que permite el análisis geográfico de los cambios de estado y la elaboración de informes de ubicación de inicio/fin de la jornada laboral

<table><thead><tr><th width="143">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>status_history_id</code> - Identificador de la entidad del historial de estado<br>- <code>device_id</code> - Identificador de la entidad dispositivo<br>- <code>old_status_id</code> - Identificador de la entidad del estado anterior<br>- <code>new_status_id</code> - Identificador de la entidad del nuevo estado<br>- <code>updated_by</code> - La fecha y hora asociadas con el atributo updated_by<br>- <code>changed_datetime</code> - Fecha y hora de la asignación de un nuevo estado en el dispositivo<br>- <code>server_datetime</code> - Fecha y hora de la asignación del nuevo estado en el servidor<br>- <code>latitude</code> - Ubicación de los dispositivos durante los cambios de estado<br>- <code>longitude</code> - Ubicación de los dispositivos durante los cambios de estado<br>- <code>address</code> - Ubicación de los dispositivos durante los cambios de estado</td></tr><tr><td><strong>Relaciones</strong></td><td>Enlaces a <code>dispositivos</code>, <code>statuses</code> (anterior y nuevo), <code>description_parameters</code> (para <code>updated_by</code> rol)</td></tr><tr><td><strong>Notas especiales</strong></td><td>La captura de ubicación permite el análisis geográfico de las transiciones de estado; útil para los informes de ubicación de inicio/fin de la jornada laboral</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Etiquetas de categorización definidas por el usuario con codificación por colores que permiten filtrar y buscar rápidamente en varios tipos de entidades (places, geofences, employees, tasks, trackers, vehicles) para una organización flexible

<table><thead><tr><th width="149">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>tag_id</code> - ID de la etiqueta de entidad<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>tag_label</code> - El atributo tag_label de la tabla tags<br>- <code>color</code> - El atributo color de la tabla tags</td></tr><tr><td><strong>Relaciones</strong></td><td>Aplicado a las entidades mediante <code>tag_links</code>; el ámbito lo define el usuario</td></tr><tr><td><strong>Notas especiales</strong></td><td>Sistema de categorización flexible que admite varias etiquetas por entidad</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Tabla de relación polimórfica que asocia etiquetas con cualquier tipo de entidad mediante entity\_type y entity\_id, con un campo ordinal para la gestión del orden de visualización, lo que permite un etiquetado flexible de múltiples entidades

<table><thead><tr><th width="127">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>tag_id</code> - ID de la etiqueta de entidad<br>- <code>entity_type</code> - El atributo entity_type de la tabla tag_links<br>- <code>entity_id</code> - Identificador de entidad<br>- <code>ordinal</code> - El atributo ordinal de la tabla tag_links</td></tr><tr><td><strong>Contenido</strong></td><td><code>entity_type</code> identifica la tabla (vehicle, employee, task, etc.); <code>ordinal</code> define el orden de visualización</td></tr><tr><td><strong>Notas especiales</strong></td><td>La relación polimórfica permite el etiquetado en distintos tipos de entidad</td></tr></tbody></table>

</details>

Grupos y jerarquía

<details>

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

**Descripción**: Estructura de agrupación organizativa para rastreadores que permite la organización visual en la interfaz de usuario con colores personalizables (group\_color) y gestión jerárquica tipo carpeta, que actualmente cumple una función puramente visual

<table><thead><tr><th width="148">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>group_id</code> - Grupo de rastreadores (vinculado por objects.group_id). La división en grupos puede verse en la lista de balizas, por ejemplo<br>- <code>client_id</code> - Identificador de la entidad cliente<br>- <code>group_label</code> - Título del grupo especificado por el usuario, de 1 a 60 caracteres imprimibles, por ejemplo "Employees"<br>- <code>group_color</code> - Color del grupo en formato web (sin #), por ejemplo "FF6DDC". Determina el color de los marcadores de los rastreadores en el mapa</td></tr><tr><td><strong>Relaciones</strong></td><td>Referenciado por <code>objects.group_id</code>; propiedad del cliente mediante <code>client_id</code> (referencias <code>users</code>)</td></tr><tr><td><strong>Notas especiales</strong></td><td>Permite la organización tipo carpeta de las entidades de monitoreo para informes y permisos</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Relación de muchos a muchos entre grupos y objetos mediante clave primaria compuesta (groups\_client\_id, objects\_client\_id), que permite que los objetos pertenezcan simultáneamente a varios grupos para estructuras organizativas flexibles

<table><thead><tr><th width="135">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>groups_client_id</code> - Identificador de entidad de cliente para grupos<br>- <code>objects_client_id</code> - Identificador de entidad de cliente para objetos</td></tr><tr><td><strong>Notas especiales</strong></td><td>Permite que los objetos pertenezcan simultáneamente a varios grupos; consulte con ambos <code>client_id</code> valores para la pertenencia al grupo</td></tr></tbody></table>

</details>

Campos personalizados y entidades

<details>

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

**Descripción**: Registro de tipos de entidad que define qué entidades empresariales admiten campos personalizados y su estructura de diseño de campos (secciones, field\_order) almacenada en entity\_label (JSONB), lo que permite la extensión dinámica del esquema en places, tasks y otras entidades sin cambios en la base de datos

<table><thead><tr><th width="141">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>entity_id</code> - Identificador de entidad<br>- <code>user_id</code> - Identificador de la entidad usuario<br>- <code>entity_label</code> - id - int. Identificador de entidad. type - enum. Actualmente, solo se admite "place". layout - object describe el diseño de los campos para la entidad. sections - array de objects. Cada section puede contener uno o más fields. Al menos debe existir una section en un layout. label - string. Nombre de la section. field_order - matriz de strings. Campos incorporados e IDs de campos personalizados (como strings)<br>- <code>builtin_type</code> - El atributo builtin_type de la tabla entities</td></tr><tr><td><strong>Relaciones</strong></td><td>Referenciado por <code>custom_fields</code> para definir qué campos personalizados se aplican a qué tipos de entidad</td></tr><tr><td><strong>Notas especiales</strong></td><td><code>builtin_type</code> vincula a <code>description_parameters</code> para clasificaciones de entidad definidas por el sistema</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Definiciones de campos personalizados que permiten la extensión dinámica del esquema para tipos de entidad, con tipos de campo configurables (custom\_field\_type), reglas de validación y opciones en parameters (JSONB), e indicadores de obligatoriedad (is\_required) para una captura de datos flexible en places, tasks y otras entidades

<table><thead><tr><th width="146">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>custom_field_id</code> - Identificador de la entidad del campo personalizado<br>- <code>entity_id</code> - Identificador de entidad<br>- <code>custom_field_label</code> - Nombre del campo<br>- <code>custom_field_type</code> - Tipo de datos del campo<br>- <code>description</code> - Descripción del campo<br>- <code>is_required</code> - ¿Es obligatorio o no?<br>- <code>parameters</code> - Parámetros del campo</td></tr><tr><td><strong>Contenido</strong></td><td><code>parameters</code> (JSONB) almacena la configuración específica del tipo de campo (reglas de validación, opciones desplegables, etc.)</td></tr><tr><td><strong>Relaciones</strong></td><td>Define los atributos personalizados disponibles para las entidades; el tipo de campo se vincula a <code>description_parameters</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Permite la extensión dinámica del esquema sin cambios en la base de datos; se usa ampliamente en <code>places</code> y <code>tasks</code></td></tr></tbody></table>

</details>

Seguimiento histórico

<details>

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

**Descripción**: Registro de auditoría completo de las asignaciones de empleado a vehículo a lo largo del tiempo, que rastrea las transiciones de old\_employee\_id a new\_employee\_id con marcas de tiempo (changed\_datetime, server\_datetime), datos de ubicación (latitude, longitude, address), información de clave de hardware y atribución de usuario (updated\_by), lo que permite análisis específicos de conductores cuando los conductores cambian entre vehículos

<table><thead><tr><th width="146">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>driver_history_id</code> - Identificador de la entidad del historial de conductor<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>old_employee_id</code> - Identificador de la entidad del empleado anterior<br>- <code>new_employee_id</code> - Identificador de la entidad del nuevo empleado<br>- <code>hardware_key</code> - El atributo hardware_key de la tabla driver_history<br>- <code>changed_datetime</code> - Fecha y hora en que se realizaron los cambios en el dispositivo<br>- <code>server_datetime</code> - Fecha y hora de los cambios realizados en el servidor<br>- <code>updated_by</code> - La fecha y hora asociadas con el atributo updated_by<br>- <code>latitude</code> - El atributo latitude de la tabla driver_history<br>- <code>longitude</code> - El atributo longitude de la tabla driver_history<br>- <code>address</code> - El atributo address de la tabla driver_history</td></tr><tr><td><strong>Relaciones</strong></td><td>Hace seguimiento de las asignaciones de conductores a vehículos a lo largo del tiempo; se vincula con <code>employees</code> y <code>objetos</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Esencial para los informes específicos de conductores cuando los conductores cambian de vehículo; la captura de ubicación permite analizar la ubicación del cambio de asignación</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Registro de auditoría que hace seguimiento de qué dispositivos GPS (object\_id) se instalaron en qué vehículos (vehicle\_id) a lo largo del tiempo con marcas de tiempo de cambio (changed\_datetime), lo que permite una atribución precisa de los datos históricos y el cálculo del kilometraje cuando los rastreadores se trasladan entre vehículos

<table><thead><tr><th width="144">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>vehicle_tracker_history_id</code> - Identificador de la entidad del historial del rastreador del vehículo<br>- <code>vehicle_id</code> - Identificador de la entidad vehículo<br>- <code>object_id</code> - Objeto identificador de entidad<br>- <code>changed_datetime</code> - La fecha y hora asociadas con el atributo changed_datetime</td></tr><tr><td><strong>Relaciones</strong></td><td>Hace seguimiento de qué dispositivo GPS se instaló en qué vehículo a lo largo del tiempo</td></tr><tr><td><strong>Notas especiales</strong></td><td>Es fundamental para el análisis de datos históricos cuando los rastreadores se trasladan entre vehículos; permite una atribución precisa del kilometraje y del uso</td></tr></tbody></table>

</details>

Datos de referencia y de consulta

<details>

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

**Descripción**: Datos de referencia de todo el sistema que proporcionan etiquetas legibles por personas (description) para valores enteros enumerados (key) utilizados en toda la base de datos, organizados por el campo type (por ejemplo, task\_status, fuel\_type, counter\_type, entity\_classification) para una traducción coherente de valores en informes y visualización de la interfaz de usuario

<table><thead><tr><th width="146">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>key</code> - Valor posible en el atributo<br>- <code>type</code> - Atributo compuesto formado por el nombre de la tabla seguido de un guion bajo y el nombre de un atributo de la tabla<br>- <code>description</code> - Valor implícito de un atributo</td></tr><tr><td><strong>Contenido</strong></td><td>Proporciona etiquetas legibles por personas para valores codificados en toda la base de datos (estado de tarea, tipos de combustible, tipos de contador, etc.)</td></tr><tr><td><strong>Relaciones</strong></td><td>Se referencia mediante claves externas desde varias tablas para una categorización estandarizada</td></tr><tr><td><strong>Notas especiales</strong></td><td>Esencial para traducir códigos enteros a valores legibles en los informes; <code>type</code> grupos de campos de enumeraciones relacionadas</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Configuraciones de odómetro y contador de horas de motor que vinculan las lecturas de sensores del dispositivo (sensor\_id) con mediciones de distancia o tiempo mediante coeficientes multiplicadores para la conversión de unidades (km, miles, hours) y counter\_type a partir de description\_parameters que define el tipo de medición

<table><thead><tr><th width="140">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>counter_id</code> - ID interno<br>- <code>device_id</code> - Identificador de la entidad dispositivo<br>- <code>counter_type</code> - Tipo de contador<br>- <code>sensor_id</code> - Identificador de la entidad sensor<br>- <code>multiplier</code> - Coeficiente para convertir valores en una de las métricas (km, l, etc.)</td></tr><tr><td><strong>Relaciones</strong></td><td>Vincula dispositivos con lecturas de sensores que representan contadores de distancia o tiempo</td></tr><tr><td><strong>Notas especiales</strong></td><td><code>multiplier</code> convierte impulsos del sensor en unidades reales (km, millas, horas); <code>counter_type</code> de <code>description_parameters</code> define el tipo de medición</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Etiquetas personalizadas para los canales de salida del dispositivo que asignan identificadores numéricos de salida (number) a nombres definidos por el usuario (label), como "Door Lock" o "Engine Block", para la elaboración de informes y análisis legibles de los comandos y estados de salida del dispositivo

<table><thead><tr><th width="140">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>device_id</code> - Identificador de la entidad dispositivo<br>- <code>number</code> - El atributo number de la tabla device_output_name<br>- <code>label</code> - El atributo label de la tabla device_output_name</td></tr><tr><td><strong>Contenido</strong></td><td>Mapea los números de los canales de salida a nombres definidos por el usuario (por ejemplo, "Door Lock", "Engine Block")</td></tr><tr><td><strong>Notas especiales</strong></td><td>Permite elaborar informes legibles al analizar los comandos y estados de salida del dispositivo</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Pares clave-valor de configuración del dispositivo sincronizados desde la plataforma de origen. Cada fila almacena un ajuste de configuración para un dispositivo específico.

<table><thead><tr><th width="140">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>device_id</code> - Identificador de la entidad dispositivo<br>- <code>key</code> - Nombre de la configuración<br>- <code>value</code> - Valor de la configuración</td></tr><tr><td><strong>Clave primaria</strong></td><td>Compuesto: <code>(device_id, key)</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Se completa durante la sincronización completa del cliente. Utilice esta tabla para leer los valores de configuración a nivel de dispositivo junto con los datos telemáticos o empresariales.</td></tr></tbody></table>

</details>

<details>

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

**Descripción**: Tabla de referencia de códigos de eventos del rastreador con descripciones legibles por personas. Contiene 134 entradas que cubren eventos comunes del rastreador como SOS, modo de suspensión, encendido y cambios de entrada/salida digital.

<table><thead><tr><th width="140">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td>- <code>event_id</code> - Código de evento (clave primaria)<br>- <code>description</code> - Nombre del evento legible por personas</td></tr><tr><td><strong>Notas especiales</strong></td><td>Unir con <code>raw_telematics_data.tracking_data_core</code> en <code>event_id</code> para mostrar los nombres de los eventos en informes y paneles en lugar de códigos numéricos.</td></tr></tbody></table>

</details>

## `raw_telematics_data` Estructura

La **`raw_telematics_data`** el esquema contiene tres tipos de tablas principales que trabajan juntas para proporcionar datos completos del dispositivo.

<figure><img src="/files/c37f37ad19aec2108d2b240b0e70c4598796572b" alt="Bronze layer raw telematics data ERD"><figcaption><p>Diagrama entidad-relación de datos telemáticos brutos de la capa Bronze</p></figcaption></figure>

{% hint style="info" %}
El diagrama interactivo del esquema raw\_telematics\_data está disponible en **dbdiagram.io**: <https://dbdiagram.io/d/v1-schema-telematics-bd-67a0acef263d6cf9a0d8e750>
{% endhint %}

A continuación encontrará los detalles del esquema de datos telemáticos brutos.

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

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

}

  

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

}

  

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

### Tablas clave por categoría

Cada tabla cumple una función específica al capturar distintos aspectos de la información del dispositivo:

<details>

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

**Propósito**: Datos principales de ubicación y movimiento

<table><thead><tr><th width="181.20001220703125">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Indexación</strong></td><td>Optimizado con índice en (<code>device_id</code>, <code>device_time</code>)</td></tr><tr><td><strong>Notas especiales</strong></td><td>Los datos de ubicación (latitude y longitude) usan formato entero con precisión de 10⁷ para un rendimiento óptimo de TimescaleDB<br><br>La velocidad también se almacena como entero, por lo que debe dividirla entre 100</td></tr></tbody></table>

</details>

<details>

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

**Propósito**: Lecturas de sensores de los dispositivos

<table><thead><tr><th width="182">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Contenido</strong></td><td>Lecturas analógicas (nivel de combustible, temperatura, voltaje), valores calculados (RPM del motor)</td></tr><tr><td><strong>Relaciones</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 estado del dispositivo y modos de funcionamiento

<table><thead><tr><th width="174.800048828125">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Contenido</strong></td><td>Indicadores de modo de funcionamiento (en funcionamiento, inactivo, apagado), estados de componentes (ignición, puertas)</td></tr><tr><td><strong>Formato del valor</strong></td><td>Valores booleanos (1/0) o códigos de estado específicos</td></tr></tbody></table>

</details>

Los datos de este esquema se ingieren directamente desde los dispositivos, con una latencia mínima (normalmente segundos). El esquema está optimizado para datos de series temporales mediante TimescaleDB para un almacenamiento y una recuperación eficientes.

## Información adicional

### Validación de datos

La base de datos garantiza la integridad de los datos mediante múltiples mecanismos:

* **Restricciones CHECK** validan que los valores se encuentren dentro de rangos aceptables
* **Claves externas** garantizan que las relaciones entre tablas se mantengan consistentes
* **Restricciones NOT NULL** garantizan que los campos obligatorios siempre tengan valores
* **Valores DEFAULT** proporcionan un valor de respaldo cuando los datos no se especifican explícitamente

### Optimización de consultas

Las tablas se organizan con estrategias de indexación específicas:

* Todas las tablas incluyen **índices basados en el tiempo** en `record_added_at`
* Las columnas de claves externas tienen índices dedicados para el rendimiento de las uniones
* Las combinaciones de columnas de uso frecuente tienen **índices compuestos**
* TimescaleDB proporciona índices especializados para consultas de series temporales

## `repo` estructura de datos

{% hint style="warning" %}
**Este esquema está actualmente en desarrollo.** Si está interesado en acceso anticipado o tiene preguntas sobre esta funcionalidad, póngase en contacto con <iotquery@navixy.com>.
{% endhint %}

La `repo` El esquema proporciona un marco integral para gestionar estructuras organizativas, activos, dispositivos y sus relaciones en entornos multiinquilino. Basado en PostgreSQL 14+ con la extensión ltree, el esquema admite organizaciones jerárquicas, definiciones de campos personalizados para cualquier tipo de entidad, control de acceso basado en roles con restricciones a nivel de objeto y trazabilidad de auditoría completa con seguimiento de cambios a nivel de campo. Todas las entidades pueden ampliarse sin modificaciones del esquema, localizarse para implementaciones internacionales y vincularse mediante relaciones polimórficas flexibles.

El esquema aborda escenarios complejos de gestión de datos, incluidas jerarquías de activos de flota en distintos niveles organizativos, plataformas SaaS multiinquilino que requieren aislamiento de datos, operaciones orientadas al cumplimiento con requisitos detallados de auditoría y sistemas que necesitan modelos de datos dinámicos adaptables mediante campos personalizados en lugar de migraciones de base de datos.

<figure><img src="/files/695ccbf99897360ebfb4346650488edd25e2f429" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
El diagrama interactivo de`repo` el esquema de datos está disponible en **dbdiagram.io**: <https://dbdiagram.io/d/Navixy-Repo-data-schema-68ad788c1e7a611967a0930e>
{% endhint %}

Encuentre los `repo` detalles del esquema a continuación.

{% code title="esquema de datos del repo" expandable="true" %}

```sql
// ============================================
// New DataHub Schema - Customer Journey
// PostgreSQL 14+ with ltree extension
// Version: 2.0 (Concept)
// ============================================

// ============================================
// BASE REFERENCE TABLES (ci_base hierarchy)
// ============================================

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
}

// ============================================
// BASE ENTITY WITH CUSTOM FIELDS SUPPORT
// ============================================

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

// ============================================
// CORE BUSINESS ENTITIES
// ============================================

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

// ============================================
// ACCESS CONTROL (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']
  }
}

// ============================================
// BUSINESS ENTITIES
// ============================================

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

// ============================================
// LOCALIZATION
// ============================================

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

// ============================================
// CUSTOM FIELDS - DEFINITIONS
// ============================================

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

// ============================================
// CUSTOM FIELDS - VALUES (by type)
// ============================================

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

// ============================================
// AUDIT
// ============================================

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

// ============================================
// RELATIONSHIPS
// ============================================

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

### Frecuencia de actualización

Los datos en el `repo` esquema se sincronizan en tiempo real con los sistemas de origen. Las actualizaciones se producen inmediatamente a medida que ocurren los cambios, y las trazas de auditoría capturan todas las modificaciones para cumplimiento y análisis histórico.

### `ci_base`

La `repo` el esquema utiliza un patrón de herencia de tabla única para todos los datos de referencia a través de la `ci_base` tabla:

La `repo` el esquema utiliza un **Patrón de herencia de tabla única** patrón para todos los datos de referencia a través de la `ci_base` tabla. Este diseño consolida diccionarios del sistema, clasificaciones y elementos de referencia definidos por el usuario en una estructura unificada, proporcionando consistencia y flexibilidad en todo el esquema.

**Arquitectura:**

La `ci_base` la tabla sirve como base para todos los datos de referencia, utilizando un campo `discriminator` para identificar el tipo de referencia específico. Cada tipo de referencia tiene una tabla correspondiente (como `ci_device_type`, `ci_asset_type`) que comparte el mismo `id` que `ci_base`, creando una relación de herencia con seguridad de tipos.

**Cómo se conectan las entidades de negocio a ci\_base:**

Todas las entidades de negocio en el `repo` referencia del esquema `ci_base` subtipos para definir su clasificación y comportamiento:

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

**Categorías de tipos de referencia:**

| Categoría                            | Tablas                                                                                                                                  | Propósito                                                                           |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| **Configuración del sistema**        | `ci_module`, `ci_country`, `ci_role`                                                                                                    | Definen los módulos del sistema, las referencias geográficas y los roles de usuario |
| **Definiciones de tipos de entidad** | `ci_entity_type`, `ci_device_type`, `ci_asset_type`, `ci_inventory_type`, `ci_organization_type`, `ci_user_type`, `ci_asset_group_type` | Clasifican todas las entidades de negocio por tipo                                  |
| **Estado y clasificación**           | `ci_device_status`, `ci_asset_type_category`                                                                                            | Rastrean los estados de las entidades y agrupan los tipos en categorías             |
| **Control de acceso**                | `ci_permission_scope`                                                                                                                   | Defina qué permisos se pueden conceder (conectado a `ci_module` y `ci_entity_type`) |
| **Relaciones**                       | `ci_device_relation_type`                                                                                                               | Defina tipos de relaciones entre dispositivos (maestro-esclavo, respaldo, etc.)     |
| **Categorización**                   | `ci_tag`, `ci_catalog_category`                                                                                                         | Permita etiquetado flexible y organización del catálogo                             |

<details>

<summary><strong>Patrones de consulta de ejemplo</strong></summary>

```sql
-- Obtener todos los tipos de dispositivo para una organización (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;

-- Obtener el tipo de activo con su categoría
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;

-- Obtener estructura jerárquica de etiquetas
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>

### Tablas clave por categoría

Las tablas de `repo` schema se organiza en categorías funcionales. Las descripciones a continuación resumen las tablas más importantes según su propósito de negocio.

<details>

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

**Propósito:** Gestión jerárquica de organizaciones

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Indexación</strong></td><td>Índice GiST en <code>path</code> para consultas jerárquicas, índices en <code>parent_id</code> y <code>organization_type_id</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Utiliza ltree para jerarquías multinivel, hereda de <code>customizable_entity</code> para soporte de campos personalizados</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Cuentas de usuario y autenticación

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Indexación</strong></td><td>Índice único en (<code>organization_id</code>, <code>identity_provider</code>, <code>identity_provider_id</code>)</td></tr><tr><td><strong>Notas especiales</strong></td><td>Integración con proveedor de identidad externo (Keycloak, Auth0, Okta), hereda de <code>customizable_entity</code></td></tr></tbody></table>

</details>

<details>

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

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

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Indexación</strong></td><td>Índices en <code>organization_id</code>, <code>device_type_id</code>, <code>status_id</code>, <code>hw_id</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Identificador de hardware para el seguimiento del dispositivo, hereda de <code>customizable_entity</code> para campos personalizados</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Activos físicos o virtuales

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Indexación</strong></td><td>Índices en <code>organization_id</code> y <code>asset_type_id</code></td></tr><tr><td><strong>Notas especiales</strong></td><td>Hereda de <code>customizable_entity</code>, vinculado a dispositivos mediante <code>device_asset_link</code></td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Registros de inventario y almacén

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</strong></td><td><code>id</code>, <code>organization_id</code>, <code>inventory_type_id</code>, <code>code</code></td></tr><tr><td><strong>Indexación</strong></td><td>Índice único en (<code>organization_id</code>, <code>code</code>)</td></tr><tr><td><strong>Notas especiales</strong></td><td>Códigos únicos dentro de la organización, vinculados a dispositivos mediante <code>device_inventory_link</code></td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Agrupación de activos con seguimiento histórico

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Relaciones</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 especiales</strong></td><td>Pertenencia basada en tiempo mediante <code>asset_group_item</code>, consulte los miembros actuales con <code>WHERE detached_at IS NULL</code></td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Definiciones y metadatos de campos personalizados

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Contenido</strong></td><td>Los tipos de campo incluyen texto, número, booleano, fecha, fecha y hora, entity_ref, catalog_item_ref</td></tr><tr><td><strong>Notas especiales</strong></td><td>Permite campos personalizados flexibles para cualquier tipo de entidad, los valores se almacenan en tablas específicas por tipo <code>custom_field_value_*</code> tablas</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Gestión de permisos basada en roles

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Contenido</strong></td><td>Máscara de bits de acción (READ=1, UPDATE=2, DELETE=4, CREATE=8), permisos específicos del objetivo o de todo el tipo de entidad</td></tr><tr><td><strong>Relaciones</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 especiales</strong></td><td>Funciona con <code>user_role</code> y <code>acl_user_scope</code> para determinar los permisos finales del usuario</td></tr></tbody></table>

</details>

<details>

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

**Propósito:** Registro de auditoría unificado para todos los cambios del sistema

<table><thead><tr><th width="139">Atributo</th><th>Detalles</th></tr></thead><tbody><tr><td><strong>Campos clave</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>Indexación</strong></td><td>Índices en (<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 especiales</strong></td><td>Particionado por <code>occurred_at</code> (mensual), dos categorías: <code>auth</code> (autenticación) y <code>domain</code> (eventos de negocio), almacena deltas de cambios a nivel de campo en <code>event_data</code> JSONB</td></tr></tbody></table>

</details>

### Relaciones de datos

La `repo` schema implementa patrones de relación sofisticados para un modelado de datos flexible:

**Estructuras jerárquicas**

* Las organizaciones usan rutas ltree para consultas de árbol eficientes
* Los elementos de referencia (`ci_base`) admiten jerarquías opcionales
* Mantenimiento automático de rutas mediante disparadores de base de datos

**Patrones de herencia**

* Herencia de tablas: `customizable_entity` → entidades de negocio (`organization`, `user`, `device`, `asset`, `inventory`, `asset_group`)
* Herencia de ID: `ci_base` → tablas de tipos de referencia
* Discriminación de tipo mediante `entity_type_id` y `discriminator` campos

**Relaciones polimórficas**

Ciertas tablas usan referencias polimórficas sin restricciones de clave foránea para máxima flexibilidad:

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

Estas relaciones se validan a nivel de aplicación.

### Información adicional

#### Validación de datos

La `repo` schema aplica la integridad de datos mediante múltiples mecanismos:

**Restricciones de base de datos**

* Restricciones UNIQUE con soporte para eliminación lógica (índices parciales WHERE `deleted_at` IS NULL)
* Restricciones CHECK (por ejemplo, `device_relation` garantiza `master_id` ≠ `slave_id`)
* Restricciones NOT NULL en campos obligatorios
* Valores DEFAULT para marcas de tiempo y banderas booleanas

**Validación a nivel de aplicación**

* Validación del tipo de entidad para referencias polimórficas
* Validación del catálogo para referencias de campos personalizados
* Validación del tipo de campo personalizado
* Gestión de arreglos de campos de múltiples valores

#### Optimización de consultas

Las tablas se organizan con estrategias de indexación específicas:

**Índices estándar:**

* Todos los campos de clave foránea tienen índices dedicados
* Índices basados en tiempo en `created_at`, `updated_at`, `deleted_at`
* Índices compuestos para columnas que se unen con frecuencia

**Índices especializados:**

* Índices GiST en rutas ltree para consultas jerárquicas
* Índices únicos parciales que admiten eliminación lógica
* Índices de valores de campos personalizados para filtrado y ordenación
* Índices de eventos de auditoría por tiempo + entidad para búsquedas eficientes

**Consideraciones de rendimiento:**

* Se recomienda la agrupación de conexiones (PgBouncer)
* Mantenimiento regular de VACUUM para tablas grandes
* Posible particionado futuro para `device` tabla por `organization_id`
* Vistas materializadas para cálculos complejos de control de acceso


---

# Agent Instructions: Querying This Documentation

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

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

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

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

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