# Lapisan data mentah

Lapisan data mentah berisi 3 skema data yang berbeda, masing-masing melayani aspek yang berbeda dari platform telematika dan business intelligence:

* [`raw_business_data`](#raw_business_data-structure) - berisi tabel, atribut, dan nilai yang terkait dengan informasi bisnis, seperti kendaraan, karyawan, geofence yang ditambahkan oleh pengguna, dll.
* [`raw_telematics_data`](#raw_telematics_data-structure) - berisi tabel, atribut, dan nilai yang terkait dengan data telematika yang dikirim dari perangkat yang dipantau, seperti lokasi, input, output, dan peristiwa.
* [`repo`](#repo-data-structure) - berisi tabel untuk manajemen aset dan inventaris, termasuk jenis aset yang dapat dikonfigurasi, field kustom, hubungan aset, dan data geospasial untuk pelacakan sumber daya organisasi.

Setiap skema dioptimalkan untuk domain data dan pola aksesnya masing-masing, sehingga menyediakan cakupan yang komprehensif untuk kebutuhan operasional, telematika, dan manajemen aset.

## `raw_business_data` struktur

Skema ini berisi 40+ tabel yang dipilih secara cermat untuk mencakup berbagai aspek bisnis dan kasus penggunaan. Tabel-tabel ini merepresentasikan entitas bisnis inti Anda, struktur organisasi, dan data operasional.

<figure><img src="/files/164cc72679b734ea40c614923aaec5d4a4e00610" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Diagram interaktif skema raw\_business\_data tersedia di **dbdiagram.io**: <https://dbdiagram.io/d/V3-bronze-layer-68ecfd1c2e68d21b4131089a>
{% endhint %}

Detail skema raw business data dapat dilihat di bawah ini.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

Tabel "groups_objects" {
  "groups_client_id" integer
  "objects_client_id" integer

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

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

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

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

### Frekuensi pembaruan

Data dalam skema ini disinkronkan dengan DB inti. Pembaruan dilakukan secara inkremental saat perubahan terjadi di basis data MySQL sumber, biasanya kurang dari 5 menit sejak perubahan sumber.

### `description_parameters`

Sistem mencakup data referensi untuk menstandarkan nilai di seluruh basis data:

<table><thead><tr><th width="167.1817626953125">Jenis referensi</th><th width="173.9090576171875">Deskripsi</th><th>Contoh nilai</th></tr></thead><tbody><tr><td>Definisi jenis</td><td>Jenis entitas standar</td><td><code>vehicle_type: car, truck, bus</code></td></tr><tr><td>Kode status</td><td>Nilai status tugas dan sistem</td><td><code>tasks_status: unassigned, assigned, done</code></td></tr><tr><td>Definisi unit</td><td>Satuan pengukuran untuk sensor</td><td><code>units_type: liter, gallon, celsius</code></td></tr><tr><td>Klasifikasi entitas</td><td>Kategori entitas bisnis</td><td><code>entities_type: place, task, customer</code></td></tr></tbody></table>

### Tabel utama berdasarkan kategori

Tabel dalam **`raw_business_data`** schema diorganisasikan ke dalam kategori fungsional agar navigasi lebih mudah. Tabel di bawah merangkum tabel utama berdasarkan tujuan bisnisnya:

Entitas bisnis inti

<details>

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

**Deskripsi**: Akun pengguna yang berisi informasi profil, afiliasi perusahaan, pengaturan pelokalan (zona waktu, locale), dan hubungan hierarkis melalui master\_id untuk struktur akun bertingkat

<table><thead><tr><th width="145">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>user_id</code> - Pengidentifikasi unik pengguna<br>- <code>company_label</code> - Nama perusahaan yang terkait dengan pengguna<br>- <code>first_name</code> - Nama pengguna<br>- <code>last_name</code> - Nama belakang pengguna<br>- <code>middle_name</code> - Nama tengah pengguna<br>- <code>locale</code> - Pengaturan bahasa pengguna<br>- <code>timezone_label</code> - Zona waktu dalam format IANA<br>- <code>master_id</code> - ID pengguna utama (jika yang saat ini adalah bawahan)<br>- <code>registration_datetime</code> - Tanggal pendaftaran di sistem<br>- <code>birth_date</code> - Tanggal lahir pengguna</td></tr><tr><td><strong>Relasi</strong></td><td>Pengguna induk melalui <code>master_id</code>, terhubung ke <code>employees</code>, <code>departments</code>, <code>places</code>, <code>tasks</code> melalui <code>user_id</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Entitas pusat yang menghubungkan data organisasi; <code>master_id</code> memungkinkan hierarki pengguna untuk struktur akun bertingkat</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Catatan karyawan dan pengemudi yang digunakan untuk merepresentasikan orang yang bekerja untuk organisasi, termasuk informasi pribadi, detail SIM, penugasan departemen, kunci perangkat keras untuk identifikasi iButton/RFID, dan data lokasi dengan dukungan geofencing

<table><thead><tr><th width="143">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>employee_id</code> - Pengidentifikasi entitas karyawan<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>department_id</code> - ID departemen tempat karyawan ditugaskan<br>- <code>first_name</code> - Atribut first_name dari tabel employees<br>- <code>last_name</code> - Atribut last_name dari tabel employees<br>- <code>middle_name</code> - Atribut middle_name dari tabel employees<br>- <code>driver_license_number</code> - Nomor SIM<br>- <code>driver_license_categories</code> - Kategori SIM<br>- <code>driver_license_issue_date</code> - Tanggal penerbitan SIM<br>- <code>driver_license_valid_till</code> - Tanggal berlaku SIM hingga<br>- <code>hardware_key</code> - Kunci perangkat keras<br>- <code>email</code> - Email karyawan<br>- <code>phone_number</code> - Nomor telepon karyawan tanpa tanda "+"<br>- <code>address</code> - Alamat lokasi<br>- <code>personnel_number</code> - Nomor personel karyawan/pengemudi<br>- <code>citizen_id_number</code> - Nomor jaminan sosial<br>- <code>latitude</code> - Lokasi yang terkait dengan karyawan ini<br>- <code>longitude</code> - Lokasi yang terkait dengan karyawan ini<br>- <code>radius</code> - Lokasi yang terkait dengan karyawan ini dalam meter<br>- <code>fuel_consumption</code> - Atribut fuel_consumption dari tabel employees<br>- <code>fuel_cost</code> - Atribut fuel_cost dari tabel employees<br>- <code>is_deleted</code> - Atribut is_deleted dari tabel employees</td></tr><tr><td><strong>Relasi</strong></td><td>Tertaut ke <code>users</code>, <code>departments</code>, <code>objects</code> (tracker yang ditugaskan), dilacak di <code>driver_history</code> dan <code>checkins</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Kunci perangkat keras memungkinkan identifikasi pengemudi melalui iButton atau RFID; mendukung geofencing dengan <code>latitude</code>, <code>longitude</code>, <code>radius</code> bidang</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Unit organisasi dengan data lokasi geografis (lintang, bujur, radius) yang memungkinkan analitik berbasis geofence untuk pelaporan tingkat departemen dan asosiasi lokasi karyawan

<table><thead><tr><th width="156">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>department_id</code> - Pengidentifikasi entitas departemen<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>department_label</code> - Atribut department_label dari tabel departments<br>- <code>latitude</code> - Lokasi yang terkait dengan departemen ini<br>- <code>longitude</code> - Lokasi yang terkait dengan departemen ini<br>- <code>radius</code> - Ukuran geolokasi dalam meter<br>- <code>address</code> - Atribut address dari tabel departments</td></tr><tr><td><strong>Relasi</strong></td><td>Menghubungkan karyawan ke struktur organisasi melalui <code>department_id</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Bidang lokasi mendukung analitik berbasis geofence untuk pelaporan tingkat departemen</td></tr></tbody></table>

</details>

Pelacakan dan pemantauan

<details>

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

**Deskripsi**: Daftar perangkat pelacak fisik dengan pengenal perangkat keras (IMEI), informasi kartu SIM, status konektivitas jaringan (kekuatan sinyal, roaming, operator), dan penetapan daftar status untuk manajemen siklus hidup perangkat

<table><thead><tr><th width="138">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>device_id</code> - ID perangkat<br>- <code>owner_id</code> - ID pemilik perangkat dalam akun tempat beacon ditambahkan<br>- <code>device_imei</code> - IMEI perangkat<br>- <code>phone</code> - Nomor kartu SIM perangkat<br>- <code>status_listing_id</code> - ID Status Perangkat<br>- <code>network_label</code> - Nama jaringan tempat kartu SIM terhubung<br>- <code>signal_level</code> - Kekuatan sinyal perangkat<br>- <code>has_roaming</code> - Penanda ketersediaan roaming<br>- <code>is_sim_blocked</code> - Penanda penguncian kartu SIM<br>- <code>created_at</code> - Tanggal dan waktu entri dibuat</td></tr><tr><td><strong>Relasi</strong></td><td>Entitas inti yang terhubung ke <code>objects</code>, <code>models</code>, <code>sensor_description</code>, <code>counters</code>; <code>owner_id</code> references <code>users.user_id</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Semua data telematika dalam <code>raw_telematics_data</code> schema merujuk ke tabel ini melalui <code>device_id</code></td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Daftar pusat entitas yang dipantau (kendaraan, aset, personel) yang menghubungkan perangkat fisik ke struktur organisasi melalui client\_id dan group\_id, merepresentasikan "unit yang dapat dilacak" dengan satu objek aktif per perangkat

<table><thead><tr><th width="148">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>client_id</code> - Pengidentifikasi entitas klien<br>- <code>device_id</code> - Pengidentifikasi entitas perangkat<br>- <code>object_label</code> - Nama objek<br>- <code>model</code> - Model perangkat<br>- <code>group_id</code> - ID grup entitas<br>- <code>create_datetime</code> - Tanggal dan waktu pembuatan baris baru di server<br>- <code>is_deleted</code> - Atribut is_deleted dari tabel objects<br>- <code>is_clone</code> - Penanda klon</td></tr><tr><td><strong>Relasi</strong></td><td>Pusat utama yang menghubungkan perangkat ke pengguna (<code>client_id</code>), detail kendaraan, riwayat pelacakan, tugas, dan aturan</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Merepresentasikan "unit yang dapat dilacak" dalam sistem; satu objek per perangkat yang sedang aktif digunakan</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Daftar pusat entitas yang dipantau (kendaraan, aset, personel) yang menghubungkan perangkat fisik ke struktur organisasi melalui client\_id dan group\_id, merepresentasikan "unit yang dapat dilacak" dengan satu objek aktif per perangkat

<table><thead><tr><th width="135">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>model_id</code> - Pengidentifikasi model entitas<br>- <code>model</code> - Atribut model dari tabel models<br>- <code>vendor</code> - Nama perusahaan yang merilis tracker<br>- <code>alternative_label</code> - Atribut alternative_label dari tabel models<br>- <code>analog_amount</code> - Jumlah input analog pada tracker<br>- <code>digital_amount</code> - Jumlah input diskret pada tracker<br>- <code>outputs_amount</code> - Jumlah output diskret tracker<br>- <code>has_battery_level</code> - Menentukan apakah tracker mengirimkan pembacaan tingkat baterai<br>- <code>has_altitude</code> - Menentukan apakah tracker mengirimkan ketinggian<br>- <code>has_phone</code> - Apakah ada kartu SIM?<br>- <code>has_gsm_level</code> - Dapatkah tracker mengirimkan kekuatan sinyal GSM?<br>- <code>has_gsm_name</code> - Dapatkah tracker mengirimkan nama jaringan GSM atau kode operator (MCC + MNC)?<br>- <code>has_gsm_roaming</code> - Dapatkah tracker mengirimkan status roaming?<br>- <code>has_detach_button</code> - Apakah tracker memiliki sensor pelepasan?<br>- <code>type_output_control</code> - Profil Kontrol Output Tracker<br>- <code>type_special_control</code> - Berisi pengaturan khusus dan modul fungsional untuk model perangkat tertentu, seperti mode berkendara berbahaya (hbm_telfm) untuk peralatan Teltonika<br>- <code>is_clone</code> - Apakah model ini klon dari model lain?</td></tr><tr><td><strong>Konten</strong></td><td>Penanda kemampuan boolean menunjukkan bidang data mana yang tersedia dari jenis perangkat ini</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Gunakan penanda kemampuan untuk menentukan sensor dan input yang valid saat melakukan kueri data telematika</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Konfigurasi sensor komprehensif yang menghubungkan input perangkat ke logika bisnis, termasuk pemetaan input, satuan pengukuran, faktor konversi (multiplier/divider), tabel kalibrasi untuk sensor bahan bakar, ambang akurasi, dan logika pengelompokan untuk pembacaan sensor teragregasi

<table><thead><tr><th width="142">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>sensor_id</code> - Pengidentifikasi entitas sensor<br>- <code>device_id</code> - Pengidentifikasi entitas perangkat<br>- <code>sensor_label</code> - Nama sensor untuk UI<br>- <code>input_label</code> - Nama bidang pesan (atribut) dari mana data sensor diambil. Jika sama dengan "input_status", itu adalah sensor diskret<br>- <code>sensor_type</code> - Jenis sensor<br>- <code>units_type</code> - Satuan pengukuran<br>- <code>multiplier</code> - Multiplier - angka yang digunakan untuk mengalikan nilai bidang. Hanya untuk sensor pengukuran<br>- <code>divider</code> - Pembagi - angka yang digunakan untuk membagi nilai bidang. Hanya untuk sensor pengukuran<br>- <code>accuracy</code> - Persentase tertentu untuk menghitung kesalahan absolut volume tangki. Kesalahan ini digunakan untuk menentukan kapan pengisian ulang atau pengurasan terjadi. Ini hanya digunakan untuk sensor bahan bakar<br>- <code>calibration_data</code> - Atribut calibration_data dari tabel sensor_description<br>- <code>input_id</code> - Nomor input untuk sensor diskret<br>- <code>group_id</code> - Sensor dengan jenis yang sama dengan group_id dan source_id yang sama dianggap termasuk dalam grup yang sama. Datanya dijumlahkan atau dirata-ratakan, tergantung pada nilai group_type. Ini diperlukan untuk sensor teragregasi. Ini digunakan pada sensor pengukuran<br>- <code>group_type</code> - 0 - jumlahkan nilai sensor dalam satu grup, 1 - rata-rata<br>- <code>sensor_units</code> - Nama satuan yang dimasukkan pengguna jika units_type=0 (kustom)<br>- <code>parameters</code> - Objek opsional dengan parameter tambahan parent_ids - array opsional dari parent_ids untuk sensor komposit. volume - double. Opsional. Volume untuk sensor komposit. parent_ids - opsional. Array int. Array parent_ids untuk sensor komposit. volume - opsional. Double. Volume untuk sensor komposit. min - opsional. Double. Nilai mentah minimum yang dapat diterima untuk sensor. max - opsional. Double. Nilai mentah maksimum yang dapat diterima untuk sensor. max_lowering_by_time - opsional. Double. Penurunan nilai legal maksimum per jam. max_lowering_by_mileage - opsional. Double. Penurunan nilai legal maksimum per 100 km. ignore_drains_in_move - opsional. Boolean. Defaultnya false. Jika true, pengurasan bahan bakar tidak akan terdeteksi saat bergerak. ignore_refuels_in_move - opsional. Boolean. Defaultnya false. Jika true, pengisian bahan bakar tidak akan terdeteksi saat bergerak. refuel_gap_minutes - opsional. Integer. Defaultnya 5. Waktu dalam menit setelah awal pergerakan, pengisian bahan bakar akan terdeteksi saat bergerak. custom_field_name - opsional. Boolean. Default false. Parameter ini menentukan apakah bidang input_name adalah nilai kustom yang dimasukkan oleh pengguna. Ini hanya masuk akal jika model tracker memiliki fitur has_custom_fields</td></tr><tr><td><strong>Relasi</strong></td><td>Menghubungkan input perangkat (dari <code>raw_telematics_data.inputs</code>) ke logika bisnis melalui <code>device_id</code> dan <code>input_label</code> pencocokan</td></tr><tr><td><strong>Catatan khusus</strong></td><td><code>calibration_data</code> (JSONB) menyimpan tabel kalibrasi khusus sensor untuk sensor tingkat bahan bakar; <code>multiplier</code> dan <code>divider</code> mengonversi nilai mentah ke satuan</td></tr></tbody></table>

</details>

Manajemen aset

<details>

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

**Deskripsi**: Daftar kendaraan komprehensif yang berisi spesifikasi (dimensi, berat, kapasitas), dokumen (VIN, registrasi, asuransi), parameter operasional (konsumsi bahan bakar, volume tangki), dan penetapan tracker saat ini melalui object\_id untuk manajemen armada dan pelacakan kepatuhan

<table><thead><tr><th width="144">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>vehicle_id</code> - Pengidentifikasi entitas kendaraan<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>garage_id</code> - Pengidentifikasi entitas garasi<br>- <code>vehicle_label</code> - Atribut vehicle_label dari tabel vehicles<br>- <code>registration_number</code> - Nomor registrasi/plat kendaraan<br>- <code>vin</code> - Atribut vin dari tabel vehicles<br>- <code>manufacture_year</code> - Atribut manufacture_year dari tabel vehicles<br>- <code>fuel_type</code> - Atribut fuel_type dari tabel vehicles<br>- <code>fuel_cost</code> - Atribut fuel_cost dari tabel vehicles<br>- <code>fuel_tank_volume</code> - Atribut fuel_tank_volume dari tabel vehicles<br>- <code>max_speed</code> - Atribut max_speed dari tabel vehicles<br>- <code>model</code> - Atribut model dari tabel vehicles<br>- <code>color</code> - Atribut color dari tabel vehicles<br>- <code>trailer</code> - Atribut trailer dari tabel vehicles<br>- <code>additional_info</code> - Atribut additional_info dari tabel vehicles<br>- <code>vehicle_type</code> - Atribut vehicle_type dari tabel vehicles<br>- <code>vehicle_subtype</code> - Atribut vehicle_subtype dari tabel vehicles<br>- <code>vehicle_status_id</code> - Pengidentifikasi entitas status kendaraan<br>- <code>chassis_number</code> - Atribut chassis_number dari tabel vehicles<br>- <code>frame_number</code> - Atribut frame_number dari tabel vehicles<br>- <code>trailer_reg_number</code> - Atribut trailer_reg_number dari tabel vehicles<br>- <code>payload_weight</code> - Atribut payload_weight dari tabel vehicles<br>- <code>payload_height</code> - Atribut payload_height dari tabel vehicles<br>- <code>payload_length</code> - Atribut payload_length dari tabel vehicles<br>- <code>payload_width</code> - Atribut payload_width dari tabel vehicles<br>- <code>passenger_capacity</code> - Jumlah maksimum penumpang<br>- <code>gross_weight</code> - Atribut gross_weight dari tabel vehicles<br>- <code>standard_fuel_consumption</code> - Konsumsi bahan bakar rata-rata normal dalam liter per 100 km<br>- <code>fuel_grade</code> - Atribut fuel_grade dari tabel vehicles<br>- <code>wheel_arrangement</code> - Atribut wheel_arrangement dari tabel vehicles<br>- <code>tyre_size</code> - Ukuran kendaraan: dimensi dan ukuran roda<br>- <code>tyres_number</code> - Jumlah roda<br>- <code>liability_insurance_policy_number</code> - Atribut liability_insurance_policy_number dari tabel vehicles<br>- <code>liability_insurance_valid_till</code> - Tanggal berlaku asuransi tanggung gugat hingga<br>- <code>free_insurance_policy_number</code> - Atribut free_insurance_policy_number dari tabel vehicles<br>- <code>free_insurance_valid_till_date</code> - Tanggal berlaku asuransi gratis hingga</td></tr><tr><td><strong>Relasi</strong></td><td>Tertaut ke <code>objects</code> (tracker saat ini), <code>garages</code> (lokasi layanan), <code>vehicle_service_tasks</code>; dilacak di <code>vehicle_trackers_history</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Bidang dimensi fisik (<code>payload_length</code>, <code>payload_width</code>, <code>payload_height</code>, <code>gross_weight</code>) mendukung analitik perencanaan muatan; tanggal asuransi memungkinkan pelacakan kepatuhan</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Lokasi fasilitas servis dan perawatan dengan koordinat geografis (lintang, bujur, radius), informasi kontak untuk mekanik dan dispatcher, yang memungkinkan deteksi kunjungan servis berbasis geofence dan analisis kedekatan

<table><thead><tr><th width="135">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>garage_id</code> - Pengidentifikasi entitas garasi<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>latitude</code> - Objek lokasi<br>- <code>longitude</code> - Objek lokasi<br>- <code>radius</code> - Ukuran geolokasi dalam meter<br>- <code>address</code> - Objek lokasi<br>- <code>organization_label</code> - ID depot<br>- <code>mechanic_name</code> - Nama mekanik<br>- <code>dispatcher_name</code> - Nama dispatcher</td></tr><tr><td><strong>Relasi</strong></td><td>Dirujuk oleh <code>vehicles.garage_id</code> untuk penetapan lokasi layanan</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Bidang lokasi memungkinkan deteksi kunjungan servis berbasis geofence dan analisis kedekatan</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Pelacakan jadwal perawatan dan riwayat servis dengan berbagai jenis pemicu (berdasarkan tanggal, berdasarkan jarak tempuh, berdasarkan jam mesin), interval tugas berulang, notifikasi multi-saluran (email, SMS, push), dan pembedaan antara peristiwa perawatan terencana (is\_repeat) dan tidak terencana

<table><thead><tr><th width="132">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>service_task_id</code> - Pengidentifikasi entitas tugas servis<br>- <code>vehicle_id</code> - Pengidentifikasi entitas kendaraan<br>- <code>description</code> - Atribut description dari tabel vehicle_service_tasks<br>- <code>status</code> - Nilai status dari atribut status<br>- <code>cost</code> - Atribut cost dari tabel vehicle_service_tasks<br>- <code>start_date</code> - Tanggal dan waktu yang terkait dengan atribut start_date<br>- <code>end_date</code> - Tanggal dan waktu yang terkait dengan atribut end_date<br>- <code>completion_date</code> - Tanggal dan waktu yang terkait dengan atribut completion_date<br>- <code>predicted_datetime</code> - Tanggal dan waktu yang terkait dengan atribut predicted_datetime<br>- <code>mileage_limit</code> - Atribut mileage_limit dari tabel vehicle_service_tasks<br>- <code>engine_hours_limit</code> - Atribut engine_hours_limit dari tabel vehicle_service_tasks<br>- <code>start_mileage</code> - Atribut start_mileage dari tabel vehicle_service_tasks<br>- <code>start_engine_hours</code> - Atribut start_engine_hours dari tabel vehicle_service_tasks<br>- <code>mileage_notification_interval</code> - Atribut mileage_notification_interval dari tabel vehicle_service_tasks<br>- <code>engine_hours_notification_interval</code> - Atribut engine_hours_notification_interval dari tabel vehicle_service_tasks<br>- <code>date_notification_interval</code> - Mengonversi bilangan bulat N menjadi N hari<br>- <code>mileage_repeat_interval</code> - Atribut mileage_repeat_interval dari tabel vehicle_service_tasks<br>- <code>engine_hours_repeat_interval</code> - Atribut engine_hours_repeat_interval dari tabel vehicle_service_tasks<br>- <code>date_repeat_interval</code> - Mengonversi bilangan bulat N menjadi N hari<br>- <code>notification_emails</code> - Atribut notification_emails dari tabel vehicle_service_tasks<br>- <code>notification_sms_phone_numbers</code> - Atribut notification_sms_phone_numbers dari tabel vehicle_service_tasks<br>- <code>is_notification_push_enabled</code> - Atribut is_notification_push_enabled dari tabel vehicle_service_tasks<br>- <code>completion_mileage</code> - Atribut completion_mileage dari tabel vehicle_service_tasks<br>- <code>completion_engine_hours</code> - Atribut completion_engine_hours dari tabel vehicle_service_tasks<br>- <code>is_repeat</code> - Atribut is_repeat dari tabel vehicle_service_tasks<br>- <code>is_unplanned</code> - Atribut is_unplanned dari tabel vehicle_service_tasks<br>- <code>comment</code> - Atribut comment dari tabel vehicle_service_tasks</td></tr><tr><td><strong>Konten</strong></td><td>Mendukung tiga jenis pemicu: berdasarkan tanggal, berdasarkan jarak tempuh, berdasarkan jam mesin; pengaturan notifikasi untuk email, SMS, push</td></tr><tr><td><strong>Catatan khusus</strong></td><td><code>is_repeat</code> dan bidang interval memungkinkan jadwal perawatan berulang; <code>is_unplanned</code> membedakan perawatan terjadwal vs. reaktif</td></tr></tbody></table>

</details>

Lokasi dan perutean

<details>

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

**Deskripsi**: Area bergeofence yang mendefinisikan perimeter virtual menggunakan lingkaran atau poligon untuk memantau peristiwa masuk dan keluar kendaraan/aset, mendukung otomatisasi berbasis aturan dan analitik lokasi dengan pengodean warna untuk diferensiasi visual

<table><thead><tr><th width="150">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>zone_id</code> - Pengidentifikasi entitas zona<br>- <code>client_id</code> - Pengidentifikasi entitas klien<br>- <code>zone_label</code> - Atribut zone_label dari tabel zones<br>- <code>zone_type</code> - Atribut zone_type dari tabel zones<br>- <code>latitude</code> - Objek opsional, kotak pembatas yang dapat sepenuhnya memuat hasil yang dikembalikan<br>- <code>longitude</code> - Objek opsional, kotak pembatas yang dapat sepenuhnya memuat hasil yang dikembalikan<br>- <code>circle_center_latitude</code> - Atribut circle_center_latitude dari tabel zones<br>- <code>circle_center_longitude</code> - Atribut circle_center_longitude dari tabel zones<br>- <code>radius</code> - Ukuran geolokasi dalam meter<br>- <code>address</code> - Atribut address dari tabel zones<br>- <code>color</code> - Atribut color dari tabel zones</td></tr><tr><td><strong>Konten</strong></td><td>Jenis zona mencakup circle, polygon (ditentukan melalui <code>geofence_points</code>), dan klasifikasi area khusus</td></tr><tr><td><strong>Relasi</strong></td><td>Dirujuk oleh <code>rules2zones</code>, <code>users2zones</code>; simpul poligon disimpan dalam <code>geofence_points</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Fungsi PostGIS dapat digunakan untuk memeriksa titik-dalam-poligon untuk analisis geofence yang kompleks</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Titik minat dengan koordinat geografis, definisi radius, dan dukungan field kustom yang dapat diperluas untuk menyimpan informasi kontak pelanggan dan data khusus bisnis, memungkinkan integrasi CRM/ERP melalui external\_id dan pelaporan berbasis lokasi

<table><thead><tr><th width="129">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>place_id</code> - Pengidentifikasi entitas tempat<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>place_label</code> - Atribut place_label dari tabel places<br>- <code>latitude</code> - Objek lokasi<br>- <code>longitude</code> - Objek lokasi<br>- <code>radius</code> - Ukuran geolokasi dalam meter<br>- <code>address</code> - Atribut address dari tabel places<br>- <code>description</code> - Atribut description dari tabel places<br>- <code>external_id</code> - ID untuk integrasi dengan sistem eksternal (CRM)<br>- <code>custom_fields</code> - Bidang tambahan<br>- <code>assigned_datetime</code> - Tanggal dan waktu penetapan titik minat kepada pengguna</td></tr><tr><td><strong>Relasi</strong></td><td>Diperluas dengan nilai bidang kustom melalui <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>Catatan khusus</strong></td><td><code>custom_fields</code> JSONB menyediakan akses cepat; tabel terkait memungkinkan penyaringan dan pengurutan pada atribut kustom</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Koordinat simpul berurutan (bidang number menentukan urutan) yang mendefinisikan batas poligon untuk bentuk geofence kompleks, memungkinkan batas geografis presisi di luar zona melingkar sederhana, digunakan dengan PostGIS ST\_MakePolygon untuk operasi geometris

<table><thead><tr><th width="133">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>zone_id</code> - ID zona yang dilampirkan ke formulir ini<br>- <code>number</code> - Nomor seri<br>- <code>latitude</code> - Lokasi<br>- <code>longitude</code> - Lokasi</td></tr><tr><td><strong>Relasi</strong></td><td>Beberapa catatan per <code>zone_id</code> menentukan batas poligon; <code>number</code> bidang menentukan urutan simpul</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Lakukan kueri dengan <code>ORDER BY number</code> untuk merekonstruksi jalur poligon; gunakan dengan PostGIS ST_MakePolygon untuk operasi geometris</td></tr></tbody></table>

</details>

Manajemen tugas dan alur kerja

<details>

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

**Deskripsi**: Penugasan pesanan kerja dengan validasi lokasi (latitude, longitude, radius), jendela waktu (time\_from, time\_to), persyaratan durasi kunjungan (stay\_duration\_minutes, arrival\_duration\_minutes), struktur hierarkis melalui parent\_task\_id, dan pelacakan status untuk manajemen layanan lapangan dan operasi pengiriman

<table><thead><tr><th width="130">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>task_id</code> - Identitas entitas tugas<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>parent_task_id</code> - Identitas entitas tugas induk<br>- <code>task_label</code> - Atribut task_label pada tabel tasks<br>- <code>status</code> - Nilai status dari atribut status<br>- <code>task_type</code> - Jenis tugas, task, route, atau checkpoint<br>- <code>latitude</code> - Atribut latitude pada tabel tasks<br>- <code>longitude</code> - Atribut longitude pada tabel tasks<br>- <code>radius</code> - Ukuran geolokasi dalam meter<br>- <code>arrival_datetime</code> - Saat pelacak tiba di area tugas. DIABAIKAN saat membuat/memperbarui<br>- <code>created_at</code> - Atribut created_at pada tabel tasks<br>- <code>status_change_datetime</code> - Tanggal dan waktu pembaruan tugas<br>- <code>time_from</code> - Tanggal dan waktu yang terkait dengan atribut time_from<br>- <code>time_to</code> - Tanggal dan waktu yang terkait dengan atribut time_to<br>- <code>stay_duration</code> - Atribut stay_duration pada tabel tasks<br>- <code>stay_duration_minutes</code> - Durasi kunjungan. Waktu yang harus dihabiskan pekerja lapangan di lokasi penugasan untuk menyelesaikan tugas dengan sukses. Beberapa kunjungan bersifat kumulatif<br>- <code>arrival_duration_minutes</code> - Abaikan kunjungan acak yang lebih singkat daripada durasi yang ditentukan. Saat menghitung durasi minimum, kunjungan yang lebih singkat daripada durasi yang ditentukan akan diabaikan<br>- <code>max_delay_minuts</code> - Keterlambatan yang dapat diterima. Jumlah maksimum waktu yang dapat dihabiskan karyawan untuk terlambat. Setiap tugas yang diselesaikan selama waktu ini akan ditandai sebagai "terlambat"<br>- <code>is_stay_control_enabled</code> - Atribut is_stay_control_enabled pada tabel tasks<br>- <code>address</code> - Atribut address pada tabel tasks<br>- <code>description</code> - Atribut description pada tabel tasks<br>- <code>custom_fields</code> - Atribut custom_fields pada tabel tasks<br>- <code>external_id</code> - Identitas entitas eksternal<br>- <code>order_sort</code> - Atribut order_sort pada tabel tasks<br>- <code>created_by</code> - Sumber tugas yang dibuat</td></tr><tr><td><strong>Konten</strong></td><td>Mendukung tugas hierarkis melalui <code>parent_task_id</code>; jendela waktu ditentukan oleh <code>time_from</code>/<code>time_to</code>; validasi geofence dengan lokasi dan radius</td></tr><tr><td><strong>Relasi</strong></td><td>Tertaut ke <code>formulir</code> (pengumpulan data), <code>task_history</code> (perubahan status), <code>objects</code> (pelacak yang ditugaskan)</td></tr><tr><td><strong>Catatan khusus</strong></td><td><code>stay_duration</code> dan <code>arrival_duration_minutes</code> memungkinkan pemantauan kepatuhan untuk tugas pengiriman dan layanan</td></tr></tbody></table>

</details>

<details>

<summary><strong><code>formulir</code></strong></summary>

**Deskripsi**: Formulir pengumpulan data yang dapat dikonfigurasi untuk menangkap informasi terstruktur selama penyelesaian tugas atau check-in aplikasi seluler, dengan bidang dan nilai disimpan sebagai JSON, validasi lokasi opsional (is\_submission\_in\_zone), dan persyaratan pengiriman wajib saat dilampirkan ke tugas

<table><thead><tr><th width="141">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>form_id</code> - Identitas entitas formulir<br>- <code>task_id</code> - ID tugas yang dilampiri formulir ini<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>form_label</code> - Label formulir yang ditentukan pengguna<br>- <code>bidang</code> - Jika true, formulir hanya dapat dikirim di zona tugas<br>- <code>values</code> - Peta dengan ID bidang sebagai kunci dan objek field_value sebagai nilai. Kunci digunakan untuk menghubungkan bidang dan nilai yang sesuai<br>- <code>submitted_at</code> - Tanggal saat nilai formulir terakhir dikirim<br>- <code>submission_latitude</code> - Lokasi tempat nilai formulir terakhir dikirim<br>- <code>submission_longitude</code> - Lokasi tempat nilai formulir terakhir dikirim<br>- <code>submission_address</code> - Lokasi tempat nilai formulir terakhir dikirim<br>- <code>is_submission_in_zone</code> - Jika true, formulir hanya dapat dikirim di zona tugas<br>- <code>description</code> - Tanggal saat formulir ini dibuat (atau dilampirkan ke tugas)<br>- <code>created_at</code> - Tanggal saat formulir ini dibuat (atau dilampirkan ke tugas)</td></tr><tr><td><strong>Konten</strong></td><td><code>bidang</code> menentukan struktur formulir (JSON); <code>values</code> berisi data yang dikirimkan (JSON)</td></tr><tr><td><strong>Relasi</strong></td><td>Tertaut ke <code>tasks</code> (pesanan kerja terkait), <code>objects</code> (pengirim), dirujuk dalam <code>checkins</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Bendera validasi lokasi <code>is_submission_in_zone</code> memungkinkan aturan pengiriman formulir berbasis geofence</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Catatan kehadiran dan aktivitas berbasis lokasi yang dikirim melalui aplikasi seluler, melacak waktu kedatangan yang direncanakan versus aktual (planned\_datetime vs actual\_datetime) dengan koordinat geografis dan pengukuran akurasi lokasi (radius) untuk pelaporan ketepatan waktu

<table><thead><tr><th width="129">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>checkin_id</code> - Identitas entitas checkin<br>- <code>employee_id</code> - Identitas entitas karyawan juga merupakan identitas untuk pengemudi<br>- <code>object_id</code> - Perangkat karyawan<br>- <code>form_id</code> - Identitas entitas formulir<br>- <code>user_id</code> - Pengguna karyawan<br>- <code>planned_datetime</code> - Waktu perangkat saat check-in dilakukan<br>- <code>actual_datetime</code> - Waktu server saat permintaan/pesan diproses<br>- <code>latitude</code> - Lokasi tempat check-in dikirim<br>- <code>longitude</code> - Lokasi tempat check-in dikirim<br>- <code>radius</code> - Kesalahan penentuan posisi pada suatu titik dalam meter<br>- <code>address</code> - Alamat check-in<br>- <code>comment</code> - Atribut comment pada tabel checkins</td></tr><tr><td><strong>Relasi</strong></td><td>Menghubungkan karyawan ke formulir dan lokasi; melacak penyimpangan dari jadwal yang direncanakan</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Varians waktu antara <code>planned_datetime</code> dan <code>actual_datetime</code> memungkinkan pelaporan ketepatan waktu; radius menentukan toleransi lokasi yang dapat diterima</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Jejak audit lengkap dari peristiwa siklus hidup tugas yang menangkap semua perubahan status, penugasan, pembaruan, dan modifikasi bidang dengan stempel waktu (event\_datetime), atribusi pengguna, dan jenis aktivitas (create, update, assign, status\_change) yang disimpan di bidang payload untuk kepatuhan dan analisis alur kerja

<table><thead><tr><th width="137">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>task_history_id</code> - Identitas entitas riwayat tugas<br>- <code>task_id</code> - Identitas entitas tugas<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>activity</code> - Operasi yang terjadi. Dapat berupa "create", "update", "assign" atau "status_change"<br>- <code>event_datetime</code> - Tanggal dan waktu kejadian<br>- <code>payload</code> - Bergantung pada operasi. Biasanya, berisi bidang yang diubah selama operasi</td></tr><tr><td><strong>Konten</strong></td><td>Jenis aktivitas didefinisikan dalam <code>description_parameters</code>; <code>payload</code> menyimpan detail khusus peristiwa (teks)</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Penting untuk analisis penyelesaian tugas, pelaporan transisi status, dan pelacakan aktivitas pengguna</td></tr></tbody></table>

</details>

Aturan dan otomatisasi

<details>

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

**Deskripsi**: Aturan deteksi peristiwa dengan kondisi pemicu yang dapat dikonfigurasi (pelanggaran kecepatan, pelanggaran geofence, ambang batas sensor, waktu idle) yang disimpan dalam parameters (JSONB), dan pengaturan notifikasi multi-saluran (alert\_email, alert\_sms, alert\_phone, is\_push\_enabled) untuk pemantauan dan peringatan otomatis berdasarkan data perangkat dan server

<table><thead><tr><th width="131">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>rule_id</code> - Identitas entitas aturan<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>client_id</code> - Pengidentifikasi entitas klien<br>- <code>event_type</code> - Atribut event_type pada tabel rules<br>- <code>event_label</code> - Atribut event_label pada tabel rules<br>- <code>event_group</code> - Atribut event_group pada tabel rules<br>- <code>description</code> - Atribut description pada tabel rules<br>- <code>parameters</code> - Parameter peristiwa. Untuk detail lebih lanjut tentang parameter yang tersedia, lihat <a href="https://www.navixy.com/docs/navixy-api/user-api/backend-api/resources/tracking/tracker/rules/rule_types/">Dokumentasi API Navixy</a>.<br>- <code>alert_email</code> - Email untuk notifikasi<br>- <code>alert_sms</code> - Nomor telepon untuk notifikasi SMS<br>- <code>alert_phone</code> - Telepon untuk panggilan suara<br>- <code>is_push_enabled</code> - Jika true, notifikasi push tersedia<br>- <code>created_at</code> - Atribut created_at pada tabel rules<br>- <code>is_deleted</code> - Atribut is_deleted pada tabel rules<br>- <code>maksimum</code> - Batas yang diterapkan pada berbagai aturan. Misalnya, untuk aturan waktu idle dengan mesin menyala dalam menit<br>- <code>event_comment1</code> - Atribut event_comment1 pada tabel rules<br>- <code>event_comment2</code> - Atribut event_comment2 pada tabel rules</td></tr><tr><td><strong>Konten</strong></td><td>Parameter aturan (JSONB) menentukan kondisi pemicu; mendukung notifikasi email, SMS, telepon, dan push</td></tr><tr><td><strong>Relasi</strong></td><td>Tautan ke objek melalui <code>rules2objects</code>, zona melalui <code>rules2zones</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td><code>event_type</code> menentukan skenario pemantauan spesifik (pelanggaran kecepatan, pelanggaran geofence, ambang sensor); <code>maksimum</code> bidang memungkinkan agregasi peristiwa untuk peringatan berbasis ambang batas</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Relasi banyak-ke-banyak yang menghubungkan aturan dengan objek yang dipantau dengan kustomisasi parameter per objek melalui object\_params (JSONB), memungkinkan nilai ambang batas yang berbeda (misalnya, batas kecepatan) untuk setiap kendaraan atau aset dalam aturan yang sama

<table><thead><tr><th width="140">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>rule_id</code> - Identitas entitas aturan<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>param_group_number</code> - Atribut param_group_number pada tabel rules2objects<br>- <code>object_params</code> - Atribut object_params pada tabel rules2objects</td></tr><tr><td><strong>Konten</strong></td><td><code>object_params</code> (JSONB) memungkinkan kustomisasi aturan per objek (misalnya, batas kecepatan berbeda per kendaraan)</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Relasi banyak-ke-banyak memungkinkan satu aturan memantau beberapa objek dengan parameter berbeda</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Relasi banyak-ke-banyak yang mengaitkan aturan dengan zona geofence, memungkinkan satu aturan memantau peristiwa masuk/keluar di beberapa area geografis untuk skenario pemantauan spasial yang kompleks

<table><thead><tr><th width="144">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>rule_id</code> - Identitas entitas aturan<br>- <code>zone_id</code> - Identitas entitas zona</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Relasi banyak-ke-banyak memungkinkan pemantauan multi-zona untuk satu aturan (misalnya, peringatan saat memasuki salah satu dari beberapa area terbatas)</td></tr></tbody></table>

</details>

Status dan kategorisasi

<details>

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

**Deskripsi**: Definisi status kustom dalam daftar status, termasuk properti tampilan (color untuk tampilan website, order\_sort untuk penempatan) yang digunakan untuk merepresentasikan status kerja perangkat atau karyawan dengan dukungan soft delete melalui bendera is\_deleted

<table><thead><tr><th width="128">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>status_id</code> - Status identitas entitas<br>- <code>listing_id</code> - Identitas entitas daftar<br>- <code>status_label</code> - Nilai status dari atribut status_label<br>- <code>color</code> - Warna yang digunakan untuk ditampilkan di situs web<br>- <code>order_sort</code> - Posisi urut dalam status daftar<br>- <code>is_deleted</code> - Atribut is_deleted pada tabel statuses</td></tr><tr><td><strong>Relasi</strong></td><td>Kelompok status yang diatur oleh <code>listing_id</code> (merujuk ke <code>status_listings</code>); digunakan dalam <code>status_history</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td><code>order_sort</code> menentukan urutan tampilan; warna memungkinkan pembedaan visual dalam pelaporan</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Definisi set status yang mengontrol nilai status mana yang tersedia untuk perangkat atau karyawan, dengan bendera izin (is\_supervisor\_controlled, is\_employee\_controlled) yang menentukan apakah supervisor, karyawan, atau keduanya dapat mengubah nilai status

<table><thead><tr><th width="144">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>status_listing_id</code> - Identitas entitas daftar status<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>status_listing_label</code> - Nilai status dari atribut status_listing_label<br>- <code>is_supervisor_controlled</code> - Jika true, supervisor dapat mengubah status kerja, misalnya menggunakan aplikasi pemantauan seluler<br>- <code>is_employee_controlled</code> - Jika true, karyawan dapat mengubah status kerja mereka sendiri, misalnya menggunakan aplikasi pelacakan seluler<br>- <code>is_deleted</code> - Atribut is_deleted pada tabel status_listings</td></tr><tr><td><strong>Relasi</strong></td><td>Dirujuk oleh <code>devices.status_listing_id</code> dan <code>statuses.listing_id</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Bendera kontrol menentukan siapa yang dapat mengubah status: hanya supervisor, layanan mandiri karyawan, atau keduanya</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Jejak audit semua transisi status perangkat dengan stempel waktu (changed\_datetime pada perangkat, server\_datetime pada server), atribusi pengguna (updated\_by), dan penangkapan lokasi (latitude, longitude, address) yang memungkinkan analisis geografis perubahan status dan pelaporan lokasi awal/akhir hari kerja

<table><thead><tr><th width="143">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>status_history_id</code> - Status identitas entitas riwayat<br>- <code>device_id</code> - Pengidentifikasi entitas perangkat<br>- <code>old_status_id</code> - Identitas entitas status lama<br>- <code>new_status_id</code> - Identitas entitas status baru<br>- <code>updated_by</code> - Tanggal dan waktu yang terkait dengan atribut updated_by<br>- <code>changed_datetime</code> - Tanggal dan waktu penetapan status baru pada perangkat<br>- <code>server_datetime</code> - Tanggal dan waktu penetapan status server baru<br>- <code>latitude</code> - Lokasi perangkat selama perubahan status<br>- <code>longitude</code> - Lokasi perangkat selama perubahan status<br>- <code>address</code> - Lokasi perangkat selama perubahan status</td></tr><tr><td><strong>Relasi</strong></td><td>Tertaut ke <code>devices</code>, <code>statuses</code> (lama dan baru), <code>description_parameters</code> (untuk <code>updated_by</code> peran)</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Penangkapan lokasi memungkinkan analisis geografis transisi status; berguna untuk pelaporan lokasi awal/akhir hari kerja</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Label kategorisasi yang ditentukan pengguna dengan kode warna yang memungkinkan penyaringan dan pencarian cepat di berbagai jenis entitas (places, geofences, employees, tasks, trackers, vehicles) untuk pengorganisasian yang fleksibel

<table><thead><tr><th width="149">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>tag_id</code> - ID entitas tag<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>tag_label</code> - Atribut tag_label pada tabel tags<br>- <code>color</code> - Atribut color pada tabel tags</td></tr><tr><td><strong>Relasi</strong></td><td>Diterapkan pada entitas melalui <code>tag_links</code>; cakupan ditentukan oleh pengguna</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Sistem kategorisasi fleksibel yang mendukung beberapa tag per entitas</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Tabel relasi polimorfik yang mengaitkan tag dengan jenis entitas apa pun melalui entity\_type dan entity\_id, dengan bidang ordinal untuk pengelolaan urutan tampilan, memungkinkan penandaan multi-entitas yang fleksibel

<table><thead><tr><th width="127">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>tag_id</code> - ID entitas tag<br>- <code>entity_type</code> - Atribut entity_type pada tabel tag_links<br>- <code>entity_id</code> - Identitas entitas<br>- <code>ordinal</code> - Atribut ordinal pada tabel tag_links</td></tr><tr><td><strong>Konten</strong></td><td><code>entity_type</code> mengidentifikasi tabel (vehicle, employee, task, dll.); <code>ordinal</code> menentukan urutan tampilan</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Relasi polimorfik memungkinkan penandaan di berbagai jenis entitas</td></tr></tbody></table>

</details>

Grup dan hierarki

<details>

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

**Deskripsi**: Struktur pengelompokan organisasi untuk pelacak yang memungkinkan organisasi visual di antarmuka pengguna dengan warna yang dapat disesuaikan (group\_color) dan pengelolaan hierarkis seperti folder, yang saat ini berfungsi murni secara visual

<table><thead><tr><th width="148">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>group_id</code> - Grup pelacak (ditautkan oleh objects.group_id). Pembagian ke dalam grup dapat dilihat dalam daftar beacon, misalnya<br>- <code>client_id</code> - Pengidentifikasi entitas klien<br>- <code>group_label</code> - Judul grup yang ditentukan pengguna, 1 hingga 60 karakter yang dapat dicetak, misalnya "Employees"<br>- <code>group_color</code> - Warna grup dalam format web (tanpa #), misalnya "FF6DDC". Menentukan warna penanda pelacak di peta</td></tr><tr><td><strong>Relasi</strong></td><td>Dirujuk oleh <code>objects.group_id</code>; kepemilikan klien melalui <code>client_id</code> (merujuk ke <code>users</code>)</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Memungkinkan pengorganisasian entitas pemantauan seperti folder untuk pelaporan dan izin</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Relasi banyak-ke-banyak antara grup dan objek menggunakan kunci primer gabungan (groups\_client\_id, objects\_client\_id), memungkinkan objek berada di beberapa grup secara bersamaan untuk struktur organisasi yang fleksibel

<table><thead><tr><th width="135">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>groups_client_id</code> - Identitas entitas klien untuk grup<br>- <code>objects_client_id</code> - Identitas entitas klien untuk objek</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Memungkinkan objek berada di beberapa grup secara bersamaan; lakukan kueri dengan keduanya <code>client_id</code> nilai keanggotaan grup</td></tr></tbody></table>

</details>

Bidang kustom dan entitas

<details>

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

**Deskripsi**: Registri jenis entitas yang mendefinisikan entitas bisnis mana yang mendukung bidang kustom dan struktur tata letak bidangnya (sections, field\_order) yang disimpan dalam entity\_label (JSONB), memungkinkan perluasan skema dinamis di seluruh places, tasks, dan entitas lain tanpa perubahan basis data

<table><thead><tr><th width="141">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>entity_id</code> - Identitas entitas<br>- <code>user_id</code> - Pengidentifikasi entitas pengguna<br>- <code>entity_label</code> - id - int. Identitas entitas. type - enum. Saat ini, hanya "place" yang didukung. layout - object menjelaskan tata letak bidang untuk entitas. sections - array of objects. Setiap section dapat berisi satu atau lebih bidang. Setidaknya satu section harus ada dalam sebuah layout. label - string. Nama section. field_order - string array. Bidang bawaan dan ID bidang kustom (sebagai string)<br>- <code>builtin_type</code> - Atribut builtin_type pada tabel entities</td></tr><tr><td><strong>Relasi</strong></td><td>Dirujuk oleh <code>custom_fields</code> untuk menentukan bidang kustom mana yang berlaku untuk jenis entitas mana</td></tr><tr><td><strong>Catatan khusus</strong></td><td><code>builtin_type</code> terhubung ke <code>description_parameters</code> untuk klasifikasi entitas yang ditentukan sistem</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Definisi bidang kustom yang memungkinkan perluasan skema dinamis untuk jenis entitas, dengan jenis bidang yang dapat dikonfigurasi (custom\_field\_type), aturan validasi dan opsi dalam parameters (JSONB), serta bendera keharusan (is\_required) untuk penangkapan data yang fleksibel di seluruh places, tasks, dan entitas lain

<table><thead><tr><th width="146">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>custom_field_id</code> - Identitas entitas bidang kustom<br>- <code>entity_id</code> - Identitas entitas<br>- <code>custom_field_label</code> - Nama bidang<br>- <code>custom_field_type</code> - Tipe data dalam bidang<br>- <code>description</code> - Deskripsi bidang<br>- <code>is_required</code> - Apakah ini wajib atau tidak?<br>- <code>parameters</code> - Parameter bidang</td></tr><tr><td><strong>Konten</strong></td><td><code>parameters</code> (JSONB) menyimpan konfigurasi khusus tipe bidang (aturan validasi, opsi dropdown, dll.)</td></tr><tr><td><strong>Relasi</strong></td><td>Mendefinisikan atribut kustom yang tersedia untuk entitas; tipe bidang terhubung ke <code>description_parameters</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Memungkinkan perluasan skema dinamis tanpa perubahan basis data; digunakan secara luas dalam <code>places</code> dan <code>tasks</code></td></tr></tbody></table>

</details>

Pelacakan historis

<details>

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

**Deskripsi**: Jejak audit lengkap dari penugasan karyawan ke kendaraan dari waktu ke waktu yang melacak transisi old\_employee\_id ke new\_employee\_id dengan stempel waktu (changed\_datetime, server\_datetime), data lokasi (latitude, longitude, address), informasi kunci perangkat keras, dan atribusi pengguna (updated\_by) yang memungkinkan analitik khusus pengemudi saat pengemudi berpindah antar kendaraan

<table><thead><tr><th width="146">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>driver_history_id</code> - Identitas entitas riwayat pengemudi<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>old_employee_id</code> - Identitas entitas karyawan lama<br>- <code>new_employee_id</code> - Identitas entitas karyawan baru<br>- <code>hardware_key</code> - Atribut hardware_key pada tabel driver_history<br>- <code>changed_datetime</code> - Tanggal dan waktu perubahan dilakukan pada perangkat<br>- <code>server_datetime</code> - Tanggal dan waktu perubahan yang dilakukan di server<br>- <code>updated_by</code> - Tanggal dan waktu yang terkait dengan atribut updated_by<br>- <code>latitude</code> - Atribut latitude pada tabel driver_history<br>- <code>longitude</code> - Atribut longitude pada tabel driver_history<br>- <code>address</code> - Atribut address pada tabel driver_history</td></tr><tr><td><strong>Relasi</strong></td><td>Melacak penugasan pengemudi ke kendaraan dari waktu ke waktu; terhubung ke <code>employees</code> dan <code>objects</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Penting untuk pelaporan khusus pengemudi saat pengemudi berganti kendaraan; penangkapan lokasi memungkinkan analisis lokasi perubahan penugasan</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Jejak audit yang melacak perangkat GPS mana (object\_id) yang dipasang pada kendaraan mana (vehicle\_id) dari waktu ke waktu dengan stempel waktu perubahan (changed\_datetime), memungkinkan atribusi data historis yang akurat dan perhitungan jarak tempuh saat pelacak dipindahkan antar kendaraan

<table><thead><tr><th width="144">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>vehicle_tracker_history_id</code> - Identitas entitas riwayat pelacak kendaraan<br>- <code>vehicle_id</code> - Pengidentifikasi entitas kendaraan<br>- <code>object_id</code> - Objek pengidentifikasi entitas<br>- <code>changed_datetime</code> - Tanggal dan waktu yang terkait dengan atribut changed_datetime</td></tr><tr><td><strong>Relasi</strong></td><td>Melacak perangkat GPS mana yang dipasang pada kendaraan mana dari waktu ke waktu</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Sangat penting untuk analisis data historis saat pelacak dipindahkan antar kendaraan; memungkinkan atribusi jarak tempuh dan penggunaan yang akurat</td></tr></tbody></table>

</details>

Data referensi dan pencarian

<details>

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

**Deskripsi**: Data referensi di seluruh sistem yang menyediakan label yang dapat dibaca manusia (description) untuk nilai integer terhitung (key) yang digunakan di seluruh basis data, diatur berdasarkan bidang type (misalnya, task\_status, fuel\_type, counter\_type, entity\_classification) untuk translasi nilai yang konsisten dalam pelaporan dan tampilan UI

<table><thead><tr><th width="146">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>key</code> - Nilai yang mungkin pada atribut<br>- <code>type</code> - Atribut gabungan yang terdiri dari nama tabel diikuti garis bawah dan nama atribut dalam tabel<br>- <code>description</code> - Nilai implisit dari suatu atribut</td></tr><tr><td><strong>Konten</strong></td><td>Menyediakan label yang dapat dibaca manusia untuk nilai berkode di seluruh basis data (status tugas, jenis bahan bakar, jenis penghitung, dll.)</td></tr><tr><td><strong>Relasi</strong></td><td>Direferensikan melalui kunci asing dari beberapa tabel untuk kategorisasi standar</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Penting untuk menerjemahkan kode integer ke nilai yang mudah dibaca dalam pelaporan; <code>type</code> kelompok bidang enumerasi terkait</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Konfigurasi odometer dan penghitung jam mesin yang menghubungkan pembacaan sensor perangkat (sensor\_id) ke pengukuran jarak atau waktu dengan koefisien pengali untuk konversi unit (km, miles, hours) dan counter\_type dari description\_parameters yang mendefinisikan jenis pengukuran

<table><thead><tr><th width="140">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>counter_id</code> - ID internal<br>- <code>device_id</code> - Pengidentifikasi entitas perangkat<br>- <code>counter_type</code> - Jenis penghitung<br>- <code>sensor_id</code> - Pengidentifikasi entitas sensor<br>- <code>multiplier</code> - Koefisien untuk mengonversi nilai ke salah satu metrik (km, l, dll.)</td></tr><tr><td><strong>Relasi</strong></td><td>Menghubungkan perangkat ke pembacaan sensor yang mewakili penghitung jarak atau waktu</td></tr><tr><td><strong>Catatan khusus</strong></td><td><code>multiplier</code> mengonversi pulsa sensor menjadi unit aktual (km, miles, hours); <code>counter_type</code> dari <code>description_parameters</code> menentukan jenis pengukuran</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Label khusus untuk kanal output perangkat yang memetakan pengenal output numerik (number) ke nama yang ditentukan pengguna (label) seperti "Door Lock" atau "Engine Block" untuk pelaporan dan analisis yang mudah dibaca atas perintah dan status output perangkat

<table><thead><tr><th width="140">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>device_id</code> - Pengidentifikasi entitas perangkat<br>- <code>number</code> - Atribut number pada tabel device_output_name<br>- <code>label</code> - Atribut label pada tabel device_output_name</td></tr><tr><td><strong>Konten</strong></td><td>Memetakan nomor kanal output ke nama yang ditentukan pengguna (misalnya, "Door Lock", "Engine Block")</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Memungkinkan pelaporan yang mudah dibaca saat menganalisis perintah dan status output perangkat</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Pasangan key-value konfigurasi perangkat yang disinkronkan dari platform sumber. Setiap baris menyimpan satu pengaturan konfigurasi untuk perangkat tertentu.

<table><thead><tr><th width="140">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>device_id</code> - Pengidentifikasi entitas perangkat<br>- <code>key</code> - Nama pengaturan<br>- <code>value</code> - Nilai pengaturan</td></tr><tr><td><strong>Kunci primer</strong></td><td>Gabungan: <code>(device_id, key)</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Diisi selama sinkronisasi penuh klien. Gunakan tabel ini untuk membaca nilai konfigurasi tingkat perangkat bersama dengan data telematika atau bisnis.</td></tr></tbody></table>

</details>

<details>

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

**Deskripsi**: Tabel referensi kode peristiwa pelacak dengan deskripsi yang dapat dibaca manusia. Berisi 134 entri yang mencakup peristiwa pelacak umum seperti SOS, mode tidur, ignition, dan perubahan input/output digital.

<table><thead><tr><th width="140">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td>- <code>event_id</code> - Kode peristiwa (kunci utama)<br>- <code>description</code> - Nama peristiwa yang dapat dibaca manusia</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Gabungkan ke <code>raw_telematics_data.tracking_data_core</code> pada <code>event_id</code> untuk menampilkan nama peristiwa dalam laporan dan dasbor alih-alih kode numerik.</td></tr></tbody></table>

</details>

## `raw_telematics_data` struktur

Buku Resep SQL **`raw_telematics_data`** skema berisi tiga jenis tabel utama yang bekerja bersama untuk menyediakan data perangkat yang komprehensif.

<figure><img src="/files/18a41e888101a312f10e4398ff25898ec4bb6446" alt="Bronze layer raw telematics data ERD"><figcaption><p>ERD data telematika mentah lapisan Bronze</p></figcaption></figure>

{% hint style="info" %}
Diagram interaktif skema raw\_telematics\_data tersedia di **dbdiagram.io**: <https://dbdiagram.io/d/v1-schema-telematics-bd-67a0acef263d6cf9a0d8e750>
{% endhint %}

Temukan detail skema data telematika mentah di bawah ini.

{% code title="skema 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 %}

### Tabel utama berdasarkan kategori

Setiap tabel memiliki tujuan khusus dalam menangkap berbagai aspek informasi perangkat:

<details>

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

**Tujuan**: Data lokasi dan pergerakan inti

<table><thead><tr><th width="181.20001220703125">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Pengindeksan</strong></td><td>Dioptimalkan dengan indeks pada (<code>device_id</code>, <code>device_time</code>)</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Data lokasi (latitude dan longitude) menggunakan format integer dengan presisi 10⁷ untuk performa TimescaleDB yang optimal<br><br>Kecepatan juga disimpan dalam integer, jadi Anda perlu membaginya dengan 100</td></tr></tbody></table>

</details>

<details>

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

**Tujuan**: Pembacaan sensor dari perangkat

<table><thead><tr><th width="182">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Konten</strong></td><td>Pembacaan analog (level bahan bakar, suhu, tegangan), nilai terhitung (RPM mesin)</td></tr><tr><td><strong>Relasi</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>

**Tujuan**: Indikator status perangkat dan mode operasional

<table><thead><tr><th width="174.800048828125">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang Kunci</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>Konten</strong></td><td>Indikator mode operasi (bekerja, idle, mati), status komponen (ignition, doors)</td></tr><tr><td><strong>Format Nilai</strong></td><td>Nilai boolean (1/0) atau kode status tertentu</td></tr></tbody></table>

</details>

Data dalam skema ini diingest langsung dari perangkat, dengan latensi minimal (biasanya beberapa detik). Skema ini dioptimalkan untuk data deret waktu menggunakan TimescaleDB demi penyimpanan dan pengambilan yang efisien.

## Informasi tambahan

### Validasi data

Basis data menerapkan integritas data melalui beberapa mekanisme:

* **Kendala CHECK** memvalidasi bahwa nilai berada dalam rentang yang dapat diterima
* **Foreign key** memastikan hubungan antar tabel tetap konsisten
* **Kendala NOT NULL** menjamin bahwa bidang yang diwajibkan selalu memiliki nilai
* **Nilai DEFAULT** menyediakan nilai cadangan ketika data tidak diberikan secara eksplisit

### Optimasi kueri

Tabel disusun dengan strategi pengindeksan tertentu:

* Semua tabel menyertakan **indeks berbasis waktu** pada `record_added_at`
* Kolom foreign key memiliki indeks khusus untuk kinerja join
* Kombinasi kolom yang sering digunakan memiliki **indeks komposit**
* TimescaleDB menyediakan indeks khusus untuk kueri deret waktu

## `repo` struktur data

{% hint style="warning" %}
**Skema ini saat ini sedang dalam pengembangan.** Jika Anda tertarik dengan akses awal atau memiliki pertanyaan tentang fungsi ini, silakan hubungi <iotquery@navixy.com>.
{% endhint %}

Buku Resep SQL `repo` Skema ini menyediakan kerangka kerja komprehensif untuk mengelola struktur organisasi, aset, perangkat, dan hubungan di antaranya dalam lingkungan multi-tenant. Dibangun di atas PostgreSQL 14+ dengan ekstensi ltree, skema ini mendukung organisasi hierarkis, definisi bidang kustom untuk jenis entitas apa pun, kontrol akses berbasis peran dengan pembatasan pada tingkat objek, dan jejak audit lengkap dengan pelacakan perubahan pada tingkat bidang. Semua entitas dapat diperluas tanpa modifikasi skema, dilokalkan untuk penerapan internasional, dan dihubungkan melalui hubungan polimorfik yang fleksibel.

Skema ini menangani skenario pengelolaan data yang kompleks, termasuk hierarki aset armada di berbagai tingkat organisasi, platform SaaS multi-tenant yang memerlukan isolasi data, operasi yang didorong kepatuhan dengan persyaratan audit terperinci, dan sistem yang memerlukan model data dinamis yang dapat disesuaikan melalui bidang kustom alih-alih migrasi basis data.

<figure><img src="/files/605e10cbcce1bc7dc9a623e60c868eb7fe16a83a" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Diagram interaktif dari`repo` skema data tersedia di **dbdiagram.io**: <https://dbdiagram.io/d/Navixy-Repo-data-schema-68ad788c1e7a611967a0930e>
{% endhint %}

Temukan `repo` detail skema di bawah ini.

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

```sql
// ============================================
// Skema DataHub Baru - Customer Journey
// PostgreSQL 14+ dengan ekstensi ltree
// Versi: 2.0 (Konsep)
// ============================================

// ============================================
// TABEL REFERENSI DASAR (hierarki ci_base)
// ============================================

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

Table ci_module {
  id uuid [primary key]
}

Table ci_catalog_category {
  id uuid [primary key]
}

Table ci_country {
  id uuid [primary key]
}

Table ci_role {
  id uuid [primary key]
}

Table ci_entity_type {
  id uuid [primary key]
}

Table ci_device_status {
  id uuid [primary key]
}

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

Table ci_device_type {
  id uuid [primary key]
}

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

Table ci_asset_type_category {
  id uuid [primary key]
}

Table ci_inventory_type {
  id uuid [primary key]
}

Table ci_organization_type {
  id uuid [primary key]
}

Table ci_user_type {
  id uuid [primary key]
}

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

Table ci_device_relation_type {
  id uuid [primary key]
}

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

// ============================================
// ENTITAS DASAR DENGAN DUKUNGAN BIDANG KUSTOM
// ============================================

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

// ============================================
// ENTITAS BISNIS INTI
// ============================================

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

// ============================================
// KONTROL AKSES (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']
  }
}

// ============================================
// ENTITAS BISNIS
// ============================================

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

// ============================================
// LOKALISASI
// ============================================

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

// ============================================
// BIDANG KUSTOM - DEFINISI
// ============================================

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

// ============================================
// BIDANG KUSTOM - NILAI (berdasarkan tipe)
// ============================================

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

// ============================================
// HUBUNGAN
// ============================================

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

### Frekuensi pembaruan

Data dalam `repo` skema disinkronkan secara real-time dengan sistem sumber. Pembaruan terjadi segera saat perubahan berlangsung, dengan jejak audit yang menangkap semua modifikasi untuk kepatuhan dan analisis historis.

### `ci_base`

Buku Resep SQL `repo` skema menggunakan pola Single Table Inheritance untuk semua data referensi melalui `ci_base` tabel:

Buku Resep SQL `repo` skema menggunakan pola **Single Table Inheritance** untuk semua data referensi melalui `ci_base` tabel. Desain ini mengonsolidasikan kamus sistem, klasifikasi, dan item referensi yang ditentukan pengguna ke dalam satu struktur terpadu, memberikan konsistensi dan fleksibilitas di seluruh skema.

**Arsitektur:**

Buku Resep SQL `ci_base` tabel berfungsi sebagai dasar untuk semua data referensi, menggunakan bidang `discriminator` untuk mengidentifikasi tipe referensi tertentu. Setiap tipe referensi memiliki tabel yang sesuai (seperti `ci_device_type`, `ci_asset_type`) yang berbagi `id` yang sama dengan `ci_base`, sehingga menciptakan hubungan pewarisan yang aman berdasarkan tipe.

**Cara entitas bisnis terhubung ke ci\_base:**

Semua entitas bisnis dalam `repo` skema mereferensikan `ci_base` subtipe untuk menentukan klasifikasi dan perilakunya:

* `organization` → mereferensikan `ci_organization_type` (yang mewarisi dari `ci_entity_type` → `ci_base`)
* `user` → mereferensikan `ci_user_type` (yang mewarisi dari `ci_entity_type` → `ci_base`)
* `device` → mereferensikan `ci_device_type` dan `ci_device_status` (keduanya mewarisi dari `ci_base`)
* `asset` → mereferensikan `ci_asset_type` (yang mewarisi dari `ci_entity_type` → `ci_base`)
* `inventory` → mereferensikan `ci_inventory_type` (yang mewarisi dari `ci_entity_type` → `ci_base`)
* `asset_group` → mereferensikan `ci_asset_group_type` (yang mewarisi dari `ci_entity_type` → `ci_base`)

**Kategori tipe referensi:**

| Kategori                   | Tabel                                                                                                                                   | Tujuan                                                                                   |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| **Konfigurasi sistem**     | `ci_module`, `ci_country`, `ci_role`                                                                                                    | Menentukan modul sistem, referensi geografis, dan peran pengguna                         |
| **Definisi tipe entitas**  | `ci_entity_type`, `ci_device_type`, `ci_asset_type`, `ci_inventory_type`, `ci_organization_type`, `ci_user_type`, `ci_asset_group_type` | Mengklasifikasikan semua entitas bisnis berdasarkan tipe                                 |
| **Status dan klasifikasi** | `ci_device_status`, `ci_asset_type_category`                                                                                            | Melacak status entitas dan mengelompokkan tipe ke dalam kategori                         |
| **Kontrol akses**          | `ci_permission_scope`                                                                                                                   | Tentukan izin apa yang dapat diberikan (terkait dengan `ci_module` dan `ci_entity_type`) |
| **Relasi**                 | `ci_device_relation_type`                                                                                                               | Tentukan jenis hubungan antara perangkat (master-slave, cadangan, dll.)                  |
| **Kategorisasi**           | `ci_tag`, `ci_catalog_category`                                                                                                         | Memungkinkan penandaan yang fleksibel dan pengorganisasian katalog                       |

<details>

<summary><strong>Contoh pola kueri</strong></summary>

```sql
-- Ambil semua tipe perangkat untuk suatu organisasi (sistem + kustom)
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;

-- Ambil tipe aset beserta kategorinya
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;

-- Ambil struktur tag hierarkis
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>

### Tabel utama berdasarkan kategori

Tabel dalam `repo` skema diorganisasikan ke dalam kategori fungsional. Deskripsi di bawah merangkum tabel-tabel terpenting berdasarkan tujuan bisnisnya.

<details>

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

**Tujuan:** Manajemen organisasi hierarkis

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Pengindeksan</strong></td><td>Indeks GiST pada <code>path</code> untuk kueri hierarkis, indeks pada <code>parent_id</code> dan <code>organization_type_id</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Menggunakan ltree untuk hierarki multi-level, mewarisi dari <code>customizable_entity</code> untuk dukungan bidang kustom</td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Akun pengguna dan autentikasi

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Pengindeksan</strong></td><td>Indeks unik pada (<code>organization_id</code>, <code>identity_provider</code>, <code>identity_provider_id</code>)</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Integrasi penyedia identitas eksternal (Keycloak, Auth0, Okta), mewarisi dari <code>customizable_entity</code></td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Perangkat pelacak fisik

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Pengindeksan</strong></td><td>Indeks pada <code>organization_id</code>, <code>device_type_id</code>, <code>status_id</code>, <code>hw_id</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Pengidentifikasi perangkat keras untuk pelacakan perangkat, mewarisi dari <code>customizable_entity</code> untuk bidang kustom</td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Aset fisik atau virtual

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Pengindeksan</strong></td><td>Indeks pada <code>organization_id</code> dan <code>asset_type_id</code></td></tr><tr><td><strong>Catatan khusus</strong></td><td>Mewarisi dari <code>customizable_entity</code>, ditautkan ke perangkat melalui <code>device_asset_link</code></td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Catatan inventaris dan gudang

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</strong></td><td><code>id</code>, <code>organization_id</code>, <code>inventory_type_id</code>, <code>code</code></td></tr><tr><td><strong>Pengindeksan</strong></td><td>Indeks unik pada (<code>organization_id</code>, <code>code</code>)</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Kode unik dalam organisasi, ditautkan ke perangkat melalui <code>device_inventory_link</code></td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Pengelompokan aset dengan pelacakan historis

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Relasi</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>Catatan khusus</strong></td><td>Keanggotaan berbasis waktu melalui <code>asset_group_item</code>, kueri anggota saat ini dengan <code>WHERE detached_at IS NULL</code></td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Definisi dan metadata bidang kustom

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Konten</strong></td><td>Jenis bidang mencakup text, number, boolean, date, datetime, entity_ref, catalog_item_ref</td></tr><tr><td><strong>Catatan khusus</strong></td><td>Memungkinkan bidang kustom yang fleksibel untuk semua jenis entitas, nilai disimpan dalam tabel khusus tipe <code>custom_field_value_*</code> tabel</td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Manajemen izin berbasis peran

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Konten</strong></td><td>Bitmask tindakan (READ=1, UPDATE=2, DELETE=4, CREATE=8), izin spesifik target atau cakupan seluruh jenis entitas</td></tr><tr><td><strong>Relasi</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>Catatan khusus</strong></td><td>Bekerja dengan <code>user_role</code> dan <code>acl_user_scope</code> untuk menentukan izin akhir pengguna</td></tr></tbody></table>

</details>

<details>

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

**Tujuan:** Log audit terpadu untuk semua perubahan sistem

<table><thead><tr><th width="139">Atribut</th><th>Rincian</th></tr></thead><tbody><tr><td><strong>Bidang kunci</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>Pengindeksan</strong></td><td>Indeks pada (<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>Catatan khusus</strong></td><td>Dipartisi berdasarkan <code>occurred_at</code> (bulanan), dua kategori: <code>auth</code> (autentikasi) dan <code>domain</code> (peristiwa bisnis), menyimpan delta perubahan pada level bidang dalam <code>event_data</code> JSONB</td></tr></tbody></table>

</details>

### Relasi data

Buku Resep SQL `repo` skema menerapkan pola relasi yang canggih untuk pemodelan data yang fleksibel:

**Struktur hierarkis**

* Organisasi menggunakan path ltree untuk kueri pohon yang efisien
* Item referensi (`ci_base`) mendukung hierarki opsional
* Pemeliharaan path otomatis melalui trigger basis data

**Pola pewarisan**

* Pewarisan tabel: `customizable_entity` → entitas bisnis (`organization`, `user`, `device`, `asset`, `inventory`, `asset_group`)
* Pewarisan ID: `ci_base` → tabel tipe referensi
* Diskriminasi tipe melalui `entity_type_id` dan `discriminator` bidang

**Relasi polimorfik**

Tabel tertentu menggunakan referensi polimorfik tanpa batasan foreign key untuk fleksibilitas maksimum:

* `acl_role_permission.target_entity_id` → apa pun `customizable_entity`
* `acl_user_scope.target_entity_id` → apa pun `customizable_entity`
* `entity_tag.entity_id` → apa pun `customizable_entity`

Relasi ini divalidasi pada tingkat aplikasi.

### Informasi tambahan

#### Validasi data

Buku Resep SQL `repo` skema menegakkan integritas data melalui beberapa mekanisme:

**Batasan basis data**

* Batasan UNIQUE dengan dukungan soft delete (indeks parsial WHERE `deleted_at` IS NULL)
* Batasan CHECK (misalnya, `device_relation` memastikan `master_id` ≠ `slave_id`)
* Batasan NOT NULL pada bidang yang wajib
* Nilai DEFAULT untuk stempel waktu dan flag boolean

**Validasi pada tingkat aplikasi**

* Validasi jenis entitas untuk referensi polimorfik
* Validasi katalog untuk referensi bidang kustom
* Validasi jenis bidang kustom
* Manajemen larik bidang bernilai ganda

#### Optimasi kueri

Tabel disusun dengan strategi pengindeksan tertentu:

**Indeks standar:**

* Semua foreign key memiliki indeks khusus
* Indeks berbasis waktu pada `created_at`, `updated_at`, `deleted_at`
* Indeks komposit untuk kolom yang sering digabungkan

**Indeks khusus:**

* Indeks GiST pada path ltree untuk kueri hierarkis
* Indeks unik parsial yang mendukung soft delete
* Indeks nilai bidang kustom untuk penyaringan dan pengurutan
* Indeks event audit pada waktu + entitas untuk pencarian yang efisien

**Pertimbangan kinerja:**

* Disarankan penggunaan connection pooling (PgBouncer)
* Perawatan VACUUM rutin untuk tabel besar
* Kemungkinan partisi di masa depan untuk `device` tabel berdasarkan `organization_id`
* Tampilan termaterialisasi untuk perhitungan kontrol akses yang kompleks


---

# 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/id/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.
