> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Aturan Event: Velocity, Rasio, Sekuens, Korelasi

> Aturan velocity, rasio, sekuens, dan korelasi atas data event di Didit, dibuat dengan rule builder yang sama seperti aturan transaksi.

[Peristiwa](https://docs.didit.me/id/transaction-monitoring/events.md) dievaluasi oleh mesin yang sama dengan transaksi. Ada satu model aturan, satu kosakata kondisi, dan satu kumpulan tindakan. Aturan hanya perlu menyatakan jenis catatan mana yang diterapkannya.

## Berlaku untuk

`scope.record_types` menentukan pada apa aturan akan dipicu.

| `record_types` | Dipicu pada |
| - | - |
| dihilangkan atau `["transaction"]` | Hanya transaksi - **bawaan** |
| `["event"]` | Hanya peristiwa |
| `["transaction", "event"]` | Keduanya |

> [!NOTE]
>
> Jika dihilangkan, aturan tetap hanya berlaku untuk transaksi. Setiap aturan yang ditulis sebelum peristiwa tersedia berperilaku persis seperti sebelumnya, dan aturan tidak akan mulai mencocokkan login hanya karena cakupannya kosong.

Di konsol, ini adalah pemilih **Berlaku untuk** pada langkah Pemicu aturan. Jika Anda memilih Peristiwa, akan muncul daftar periksa **Kategori peristiwa** yang mempersempit aturan lebih lanjut. Biarkan semuanya tidak tercentang untuk mengevaluasi setiap kategori.

```json theme={null}
{
  "title": "Failed login burst",
  "scope": {
    "record_types": ["event"],
    "event_categories": ["security"]
  },
  "aggregation": [
    {
      "metric": "count",
      "operator": "gte",
      "value": 3,
      "window": "30m",
      "filters": {
        "subject_vendor_data": "__current__",
        "event.action_type": "login_failed"
      }
    }
  ],
  "actions": [
    { "type": "add_score", "value": 40 },
    { "type": "change_status", "value": "IN_REVIEW" }
  ]
}
```

`"__current__"` berarti "nilai yang sama dengan peristiwa yang sedang dievaluasi". Dengan cara inilah aturan menyatakan *per subjek*, *per perangkat*, atau *per putaran* tanpa perlu menyebutkan nilainya.

Catatan yang tidak memiliki nilai pengelompokan tidak pernah dikelompokkan bersama. Peristiwa tanpa sidik jari perangkat tidak dianggap "perangkat yang sama" dengan peristiwa lain yang juga tidak memilikinya, dan peristiwa yang tidak menyebutkan subjek tidak dianggap "subjek yang sama" dengan peristiwa anonim lainnya. Jika peristiwa yang sedang dievaluasi tidak memiliki nilai untuk kolom `"__current__"`, agregasi tersebut tidak akan cocok, apa pun operatornya.

## Kolom peristiwa

Kondisi membaca jalur dengan namespace. Kosakata transaksi yang sudah Anda kenal (`action_type`, `subject_vendor_data`, `subject_ip_country`, `custom_values.<key>`) juga dapat digunakan untuk peristiwa.

| Grup | Jalur |
| - | - |
| Peristiwa | `event.category`, `event.action_type`, `event.occurred_at`, `event.amount`, `event.currency`, `event.direction`, `event.session_id`, `event.session_sequence`, `event.score`, `event.status`, `event.ingest_source`, `event.retention_class`, `event.subject_vendor_data`, `event.business_vendor_data` |
| Perangkat dan jaringan | `event.device.fingerprint`, `event.device.persistent_device_id`, `event.device.bot_score`, `event.ip.address`, `event.ip.country`, `event.ip.asn_number`, `event.ip.asn_organization`, `event.ip.is_vpn_or_tor`, `event.ip.is_data_center`, `event.ip.proxy_type`, `event.ip.country_name`, `event.ip.city`, `event.ip.connection_type`, `event.ip.travel_distance_km`, `event.ip.travel_speed_kmh` |
| Permainan | `event.gameplay.game_id`, `event.gameplay.table_id`, `event.gameplay.round_id`, `event.gameplay.hand_id`, `event.gameplay.match_id`, `event.gameplay.market_id`, `event.gameplay.side`, `event.gameplay.role`, `event.gameplay.counterparty_vendor_data`, `event.gameplay.net_result_amount`, `event.bonus.bonus_id`, `event.affiliate.affiliate_code` |
| Pembayaran dan sengketa | `event.payment.reference_id`, `event.payment.payment_fingerprint`, `event.payment.instrument_reference_hash`, `event.payment.withdrawal_address_hash`, `event.dispute.dispute_id`, `event.dispute.chargeback_id` |
| Keamanan dan perjudian bertanggung jawab | `event.security.changed_field`, `event.responsible_gambling.identity_match_ref` |
| Telemetri bot dan asistensi | `event.bot.timing_variance_ms`, `event.bot.actions_per_minute`, `event.bot.pointer_entropy`, `event.bot.reaction_time_ms_p50`, `event.bot.assistance_indicator` |
| Sinyal subjek | `subject.email.risk_score`, `subject.email.social_count`, `subject.email.is_disposable`, `subject.email.deliverability`, `subject.email.domain_reputation`, `subject.email.first_seen_days`, `subject.email.is_breached`, `subject.phone.risk_score`, `subject.phone.line_type`, `subject.phone.social_count`, `subject.phone.carrier`, `subject.phone.country`, `subject.phone.is_disposable` |
| Lainnya | `event.payload.<key>`, `custom_values.<key>` |

Sinyal subjek disimpan dalam cache pada pengguna yang dipantau, tidak dihitung ulang untuk setiap peristiwa, sehingga aturan dapat membacanya dengan kecepatan penyerapan data.

## Agregasi

### Velocity

Reducer yang sudah Anda gunakan pada transaksi, yaitu `count`, `sum`, `avg`, `min`, `max`, dan `distinct_count`, dihitung atas `window` bergulir (`30m`, `24h`, `7d`, `30d`).

### Rasio

Dua reducer atas jendela yang sama. Dengan cara inilah rasio taruhan terhadap deposit, penarikan terhadap deposit, bonus terhadap deposit, dan chargeback dinyatakan.

```json theme={null}
{
  "metric": "ratio",
  "window": "24h",
  "filters": { "subject_vendor_data": "__current__" },
  "numerator":   { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "bet_placed" } },
  "denominator": { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "deposit_completed" } },
  "operator": "lte",
  "value": 0.1
}
```

Deposit 1.000, taruhan 20, lalu meminta penarikan. Rasionya 0,02, pola klasik pencucian uang dengan bermain minimal.

> [!NOTE]
>
> Rasio **tanpa penyebut tidak pernah cocok**. Tidak ada deposit bukan berarti rasionya nol. Itu berarti tidak ada bukti, dan jika aturan dipicu dalam kondisi tersebut, setiap pengguna baru akan ditandai.

### Urutan

Predikat berurutan dalam sebuah jendela. Setiap langkah mencocokkan `action_type`, `event_category`, atau filter `match` apa pun, dan dapat mensyaratkan `min_count` kemunculan sebelum urutan maju.

```json theme={null}
{
  "metric": "sequence",
  "key": "ato_drain",
  "window": "24h",
  "steps": [
    { "event_category": "security", "action_type": "login_failed", "min_count": 3 },
    { "event_category": "security", "action_type": "mfa_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_address_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_requested" }
  ]
}
```

Serangan credential stuffing, lalu pengambilalihan MFA, lalu pengalihan pembayaran, lalu penguras dana. Aturan dipicu pada peristiwa yang melengkapi rantai tersebut, dan bukti yang cocok mencantumkan ID peristiwa dari setiap langkah.

Status urutan disimpan per aturan dan per subjek, sehingga status maju seiring kedatangan peristiwa dan tidak memindai ulang linimasa. Kemajuan yang lebih lama dari jendela dibuang, bukan dihitung.

### Korelasi

Penggabungan lintas subjek: mereduksi semua peristiwa yang berbagi grup dengan peristiwa ini.

```json theme={null}
{
  "metric": "correlation",
  "window": "7d",
  "pair": true,
  "group_by": ["subject_vendor_data", "event.gameplay.counterparty_vendor_data"],
  "filters": { "event.action_type": "p2p_settlement" },
  "correlate": {
    "metric": "sum",
    "field": "event.gameplay.net_result_amount",
    "filters": { "event.gameplay.role": "winner" }
  },
  "operator": "gte",
  "value": 500
}
```

`"pair": true` mencocokkan kedua ujung sebagai himpunan tanpa urutan, sehingga A→B dan B→A masuk ke grup yang sama. Inilah yang memungkinkan satu aturan melihat kedua sisi kolusi. Dumping chip, taruhan berlawanan, dan rujukan mandiri melalui afiliasi semuanya memiliki bentuk ini.

Selalu berikan `filters` pada aturan korelasi untuk mempersempit cakupannya. Tanpa filter tersebut, aturan akan mempertimbangkan setiap peristiwa dalam jendela.

## Real-time dan aturan asinkron

Sebagian aturan dapat merespons di dalam permintaan ingesti, sementara sebagian lainnya tidak.

| Dijalankan | Aturan mana |
| - | - |
| **Dalam permintaan** | Velocity, rasio, dan sekuens terbatas (jendela hingga 24 jam) |
| **Dalam hitungan menit, secara asinkron** | Aturan korelasi, dan sekuens dengan jendela lebih dari 24 jam |

Event yang aturannya masih menunggu akan dikembalikan dengan `"correlation_pending": true`. Status dan skornya diperbarui pada event yang sama setelah tahap asinkron selesai. Menjalankan ulang bersifat idempoten, sehingga aturan tidak pernah menerapkan skornya dua kali.

Pemisahan ini disengaja: kueri lintas-subjek untuk jaringan tidak boleh membuat login harus menunggu.

## Tindakan

Kosakata tindakan sama dengan aturan transaksi: `add_score`, `change_status`, `add_tags`, `add_note`, `add_to_list`, `open_case`.

Ada dua perbedaan pada event:

* `change_status` ke `AWAITING_USER` hanya berlaku untuk transaksi (tidak ada alur remediasi event), dan diterapkan sebagai `IN_REVIEW`.
* `open_case` menautkan kasus ke **subjek**, bukan ke transaksi, dan mencatat id event yang cocok pada kasus tersebut.

## Bukti

Setiap kecocokan menyimpan apa yang dilihatnya: jendela agregasi, nilai yang dihitung, nilai yang diharapkan, sampel id event, dan **sumber dari setiap kolom yang cocok**.

| Sumber | Arti |
| - | - |
| `server` | Didit menurunkannya (IP, agen pengguna, asal). Otoritatif. |
| `sdk` | SDK Didit melaporkannya dari perangkat. |
| `customer` | Sistem Anda yang menyediakannya. |

Dengan demikian, analis dapat membedakan IP yang distempel server dari petunjuk yang dikirim klien sebelum mengambil tindakan atas suatu kecocokan. Konsol menampilkan sumber di samping setiap kolom yang cocok di panel event.

## Contoh kasus

> [accordion] Pencucian uang dengan permainan minimal
>
> Deposit, permainan dengan token, penarikan cepat. Kondisi `event.action_type eq withdrawal_requested`, ditambah rasio taruhan-terhadap-deposit `lte 0.1` selama `24h`.

> [accordion] Penipuan oleh pelanggan
>
> Rasio `count(chargeback_opened)` terhadap `count(deposit_completed)` per subjek selama `30d`, `gte 0.5`. Kelompokkan berdasarkan `event.payment.payment_fingerprint`, bukan subjek, untuk menangkap satu instrumen pembayaran di berbagai akun.

> [accordion] Pengurasan akun karena pengambilalihan
>
> Sekuens `ato_drain` di atas, dengan `add_score 90` dan `change_status DECLINED`.

> [accordion] Pembuangan chip
>
> Korelasi pasangan di atas. Naikkan `value` ke jumlah yang material untuk tabel Anda, dan tambahkan `event.gameplay.game_id` ke `group_by` agar setiap game tetap terpisah.

> [accordion] Bermain dengan bot dan bantuan waktu nyata
>
> Kondisi pada `event.action_type eq bot_signal_observed`, `event.bot.timing_variance_ms lte 10` dan `event.device.bot_score gte 90`, dengan `add_tags`. Gabungkan dengan `distinct_count` dari `event.device.fingerprint` per IP untuk menemukan jaringan bot, bukan satu skrip.

> [accordion] Penghindaran pengecualian diri
>
> Kondisi pada `event.action_type eq self_exclusion_match` dan `event.payload.re_registration_attempt eq true`, dieskalasi dengan `open_case`.

## Berikutnya

> [card] [Ingesti event](https://docs.didit.me/id/transaction-monitoring/events.md)
>
> Amplop, sepuluh kategori, dan kontrak batch.

> [card] [API Aturan](https://docs.didit.me/id/transaction-monitoring/rules-api.md)
>
> Buat, perbarui, dan lakukan backtesting aturan secara programatis.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.