Ana içeriğe geç

← Rule Service Ana Sayfası

Rule Service - Event Sözleşmeleri

Giriş Eventleri

window.ready.v1

Window Service'ten gelen event

{
"event": "window.ready.v1",
"meta": {
"schema_version": 1,
"trace_id": "window-34cd...",
"producer_service": "window-service",
"produced_at": "2026-03-14T20:30:15.200Z",
"process_ms": 45
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"window_epoch": 1647353400,
"window_start_ms": 1647353400000,
"window_end_ms": 1647353450000,
"window_duration_ms": 50000,
"measurements": {
"VRMS_R": 232.5,
"VRMS_S": 234.1,
"VRMS_T": 231.8,
"IRMS_R": 15.3,
"IRMS_S": 14.9,
"IRMS_T": 15.1,
"POWER_REAL": 10245,
"POWER_REACT": 1200
},
"synthesis": {
"i_imb": 2.1,
"v_imb": 1.3,
"pf": 0.994,
"p95_rtt_ms": 125
},
"status_register": {
"value": "0x0101",
"bits": {
"STATUS_PUMP": true,
"STATUS_FAULT_MP": false,
"STATUS_FAULT_TH": false,
"STATUS_P_HIGH": false
}
}
},
"error": null
}

Önemli Alanlar:

  • context.device_id: Hangi cihazdan
  • context.stream_id: Hangi stream'deki veriler
  • data.window_epoch: Penceren zamanı
  • data.measurements: Raw ölçüm değerleri
  • data.synthesis: Hesaplanmış değerler
  • data.status_register: Cihaz durumu bitleri

Çıkış Eventleri

rule.triggered.v1

Kural tetiklendiğinde (false→true geçişi veya multi_trigger=true)

{
"event": "rule.triggered.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "rule-service",
"produced_at": "2026-03-14T20:30:20.125Z",
"process_ms": 15
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"group_id": 12,
"rule_id": 114,
"event_type": "trigger",
"rule_hash": "a8be3f9c2e1d...",
"source_event": "window.ready.v1",
"trigger_reason": "VRMS_R > 250 AND duration >= 600s",
"severity": "high",
"trigger_count": 57,
"multi_trigger": false,
"state_changed": true,
"actions": [
{
"action_id": 21,
"action_type": "inbox_message",
"priority": 1
},
{
"action_id": 22,
"action_type": "push_notification",
"priority": 2
},
{
"action_id": 23,
"action_type": "notify_roles",
"priority": 3
}
],
"matched_rules": {
"114": true,
"115": true
},
"match_type": "all",
"duration_sec": 615
},
"error": null
}

Event Type: trigger — Tetiklenme olayı

  • group_id: Hangi kural grubu tetiklendi
  • rule_id: Tetiklenen kural (eğer varsa)
  • trigger_reason: İnsan okunabilir koşul açıklaması
  • severity: critical/high/medium/low
  • trigger_count: Bu grubun kaç kere tetiklendiği (toplam)
  • actions: Tetiklenen aksiyon listesi
  • matched_rules: Grupta hangi kurallar true oldu
  • match_type: Kurallar AND/OR/NOT ile kombinlendi

Kullanıcı: Action Executor Service'in bu event'i dinlemesi expected.


rule.triggered.v1 (Reset Örneği)

Kural sıfırlandığında (true→false geçişi) ve notify_on_reset=true

{
"event": "rule.triggered.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "rule-service",
"produced_at": "2026-03-14T20:45:30.250Z",
"process_ms": 12
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823519
},
"data": {
"group_id": 12,
"rule_id": 114,
"event_type": "reset",
"rule_hash": "a8be3f9c2e1d...",
"source_event": "window.ready.v1",
"trigger_reason": "VRMS_R ≤ 250 AND duration reset",
"severity": "info",
"trigger_count": 57,
"multi_trigger": false,
"state_changed": true,
"actions": [
{
"action_id": 24,
"action_type": "push_notification",
"priority": 1
},
{
"action_id": 25,
"action_type": "notify_roles",
"priority": 2
}
],
"matched_rules": {
"114": false,
"115": false
},
"match_type": "all",
"previous_state": "triggered"
},
"error": null
}

Event Type: reset — Sıfırlama olayı

  • event_type = "reset"
  • severity = "info" (sorun çözülmüş)
  • actions: trigger_action_plan_id yerine reset_action_plan_id kullanılır
  • previous_state: "triggered" (ne durumdan geldiği)

rule.completed.v1

Rule değerlendirmesi tamamlandığında (tetik olsa da olmasa da)

{
"event": "rule.completed.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "rule-service",
"produced_at": "2026-03-14T20:30:20.190Z",
"process_ms": 19
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"result": "success",
"evaluation_status": "completed",
"groups_evaluated": 3,
"groups_triggered": 0,
"reason": "no_trigger",
"source_event": "window.ready.v1"
},
"error": null
}

rule.completed.v1 aşağıdaki tüm başarılı senaryolarda üretilmelidir:

  • En az bir grup tetiklendi (reason=triggered)
  • Hiçbir grup tetiklenmedi (reason=no_trigger)
  • Cihaza atanmış aktif grup yok (reason=no_rule_assigned)

Bu event, Observer için lifecycle bitiş sinyalidir.

rule.completed.v1 Enum Sozlugu

data.evaluation_status

DegerAnlami
completedRule degerlendirmesi teknik olarak basariyla tamamlandi

data.reason

DegerAnlami
triggeredEn az bir grup tetiklendi
no_triggerGruplar degerlendirildi ama hicbiri tetiklenmedi
no_rule_assignedCihaza atanmis aktif grup/kural bulunmadi

Not: evaluation_status=completed oldugunda event teknik olarak basari kabul edilir; reason sadece is sonucunun kategorisini belirtir.


action.execute.requested.v1

Action Executor'a aksiyon çalıştırması için gönderilen event

{
"event": "action.execute.requested.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "rule-service",
"produced_at": "2026-03-14T20:30:20.150Z",
"process_ms": 15
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"group_id": 12,
"rule_id": 114,
"action_id": 21,
"action_type": "inbox_message",
"channel_type": "inbox",
"severity": "high",
"request_id": "action-9f3f-8c2d-uuid",
"payload": {
"title": "High Voltage Alert",
"message": "Voltage (VRMS_R) exceeded 250V for 10 minutes. Current: 320V",
"device_name": "Farm Pump #1",
"metric": "VRMS_R",
"threshold": 250,
"current_value": 320,
"unit": "V",
"timestamp": "2026-03-14T20:30:15Z"
},
"recipients": {
"owner": true,
"admin": true,
"technician": false
},
"publish": true
},
"error": null
}

Aksiyon Tipleri:

  • inbox_message — Inbox'a mesaj
  • push_notification — Push notification
  • device_command — Cihaza komut gönder
  • notify_roles — Belirtilen rollere bildir

publish Alanı:

  • true → Mesaj push channel'da gönderilecek
  • false → Mesaj sadece inbox/audit, push yok

action.execute.requested.v1 (Push Örneği)

{
"event": "action.execute.requested.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "rule-service",
"produced_at": "2026-03-14T20:30:20.160Z",
"process_ms": 15
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"group_id": 12,
"rule_id": 114,
"action_id": 22,
"action_type": "push_notification",
"channel_type": "push",
"severity": "high",
"request_id": "action-9f3f-8c2d-uuid",
"payload": {
"template_id": 5,
"title": "⚠️ High Voltage",
"body": "VRMS_R: 320V (limit: 250V)",
"device_name": "Farm Pump #1",
"metric": "VRMS_R",
"threshold": 250,
"current_value": 320,
"delta": 70,
"unit": "V",
"timestamp": "2026-03-14T20:30:15Z"
},
"recipients": {
"owner": true,
"admin": true,
"technician": false
},
"publish": true
},
"error": null
}

action.execute.requested.v1 (Device Command Örneği)

{
"event": "action.execute.requested.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "rule-service",
"produced_at": "2026-03-14T20:30:20.170Z",
"process_ms": 15
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"group_id": 12,
"rule_id": 114,
"action_id": 26,
"action_type": "device_command",
"channel_type": "device",
"severity": "critical",
"request_id": "action-9f3f-8c2d-uuid",
"payload": {
"command_id": 7,
"command_type": "reset",
"command_name": "Emergency Reset",
"target_device_id": "400000011D081B70",
"reason": "High voltage protection",
"timeout_sec": 30
},
"publish": false
},
"error": null
}

Action Executor Tüketim Sözleşmesi

Bu bölüm, action.execute.requested.v1 event'ini tüketen Action Executor için bağlayıcı kuralları tanımlar.

Zorunlu Alanlar

Action Executor event'i işlerken aşağıdaki alanları zorunlu kabul etmelidir:

  • meta.schema_version
  • meta.trace_id
  • context.device_id
  • context.stream_id
  • data.group_id
  • data.action_id
  • data.action_type
  • data.request_id
  • data.payload

Zorunlu alanlardan biri eksikse event başarısız sayılır ve rule.failed.v1 üretimi tetiklenir.

action_type ve Beklenen payload Şeması

  • inbox_message:
    • Beklenen alanlar: title, message, timestamp
  • push_notification:
    • Beklenen alanlar: title/body veya template_id, timestamp
  • device_command:
    • Beklenen alanlar: command_id, command_type, target_device_id
  • notify_roles:
    • Beklenen alanlar: en az bir hedef alıcı (recipients.owner/admin/technician)

payload içeriği action_type ile uyumsuzsa event işlenmemelidir.

publish Davranışı

  • publish=true: Push kanalına yayın yapılabilir.
  • publish=false: Push gönderimi yapılmaz; inbox/audit benzeri iç kanallar işlenmeye devam eder.

Idempotency ve Duplicate Koruması

Action Executor aşağıdaki anahtarı idempotency key olarak kullanmalıdır:

sha1(device_id | stream_id | group_id | action_id | request_id)

Aynı anahtar tekrar gelirse ikinci ve sonraki event'ler duplicate kabul edilip skip edilmelidir.

Retry Politikası

  • Geçici hatalar (network, downstream timeout): exponential backoff ile retry.
  • Kalıcı hatalar (şema uyumsuzluğu, zorunlu alan eksikliği): retry yapılmadan failed olarak işaretlenir.
  • Önerilen retry sınırı: en fazla 3 deneme.

Gözlemlenebilirlik (Observability)

Action Executor her işleme için en az aşağıdaki alanları loglamalıdır:

  • trace_id
  • request_id
  • device_id
  • action_id
  • action_type
  • result (success / failed / duplicate_skipped)
  • latency_ms

Action Executor Response Eventleri

Action Executor, action.execute.requested.v1 event'ini işledikten sonra aşağıdaki ack eventlerinden birini üretmelidir.

action.executed.v1

Aksiyon başarıyla tamamlandığında

{
"event": "action.executed.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "action-executor-service",
"produced_at": "2026-03-14T20:30:20.420Z",
"process_ms": 28
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"request_id": "action-9f3f-8c2d-uuid",
"group_id": 12,
"rule_id": 114,
"action_id": 21,
"action_type": "inbox_message",
"result": "success",
"executed_at": "2026-03-14T20:30:20.415Z",
"delivery": {
"channel": "inbox",
"provider_message_id": "inbox-3b12a9",
"status": "sent"
}
},
"error": null
}

action.failed.v1

Aksiyon kalıcı veya geçici hata ile tamamlanamadığında

{
"event": "action.failed.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "action-executor-service",
"produced_at": "2026-03-14T20:30:21.010Z",
"process_ms": 210
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"request_id": "action-9f3f-8c2d-uuid",
"group_id": 12,
"rule_id": 114,
"action_id": 22,
"action_type": "push_notification",
"result": "failed",
"attempt": 3,
"max_attempt": 3,
"failed_at": "2026-03-14T20:30:21.002Z"
},
"error": {
"error_code": "PUSH_PROVIDER_TIMEOUT",
"error_message": "push provider timeout after 5s",
"retryable": true,
"failed_stage": "provider_call"
}
}

Correlation ve Tüketim Kuralı

  • Rule Service, request_id üzerinden request/response eşlemesi yapar.
  • action.executed.v1 geldiğinde ilgili aksiyon başarıyla tamamlandı olarak işaretlenir.
  • action.failed.v1 geldiğinde retryable durumuna göre yeniden deneme veya kalıcı hata kaydı uygulanır.
  • Aynı request_id için birden fazla ack event gelirse idempotency kuralı uygulanır; ilk terminal sonuç geçerli kabul edilir.

Hata Eventleri

rule.failed.v1

Kural değerlendirme sırasında hata olduğunda

{
"event": "rule.failed.v1",
"meta": {
"schema_version": 1,
"trace_id": "rule-9f3f-8c2d...",
"producer_service": "rule-service",
"produced_at": "2026-03-14T20:30:21.180Z",
"process_ms": 15
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": null,
"error": {
"failed_stage": "rule_evaluation",
"error_code": "RULE_CONDITION_INVALID",
"error_message": "unknown variable in rule: P95_X",
"rule_id": 114,
"group_id": 12,
"retryable": false,
"failed_at": "2026-03-14T20:30:21Z",
"stacktrace": "com.example.rule.RuleEvaluator.evaluate..."
}
}

Error Codes:

  • RULE_CONDITION_INVALID — Kural tanımı hatalı
  • VARIABLE_NOT_FOUND — Ölçüm değişkeni bulunamadı
  • CACHE_MISS_DB_UNAVAILABLE — Redis ve DB inaccessible
  • DEVICE_NOT_FOUND — Cihaz bulunamadı
  • GROUP_NOT_FOUND — Kural grubu bulunamadı
  • MALFORMED_EVENT — Event payload hatalı

retryable:

  • true → Retry etmek mantıklı (e.g., temporary connection issue)
  • false → Permanent error (e.g., invalid rule definition)

Event Ordering Guarantees

Per-Device Ordering

Events bir cihaz için FIFO garantilidir.

Device E2E-001:
├─ window.ready.v1 (stream_id=9823412) → rule.triggered.v1 (group_id=12) → rule.completed.v1
├─ window.ready.v1 (stream_id=9823413) → rule.completed.v1 (reason=no_trigger)
├─ window.ready.v1 (stream_id=9823414) → rule.triggered.v1 (group_id=15)

Order: garantili

Cross-Device Ordering

Farklı cihazlar arasında ordering garantisi yoktur.

Device E2E-001: rule.triggered.v1@20:30:20Z
Device E2E-002: rule.triggered.v1@20:30:19Z

Order: Tanımsız (producer'ın paralel işleme yapması)

Idempotency

Rule Service tüm output events idempotent yapmalıdır.

Idempotency Key = sha1(device_id | stream_id | group_id | rule_id | event_type)

Örnek:
device_id = 400000011D081B70
stream_id = 9823412
group_id = 12
rule_id = 114
event_type = trigger

Key = sha1("400000011D081B70|9823412|12|114|trigger")
= "3f9c2e1d8a4b5c6d7e8f9g0h1i2j3k4l"

Aynı key ile duplicate event gelirse, Action Executor'da ilk event'i işlemesi expected, duplicate skip.

rule.completed.v1 için önerilen key:

sha1(device_id | stream_id | "rule.completed.v1")

Topic Naming

Events Topic Mapping:

rule.triggered.v1 → cinga.rule.triggered
rule.completed.v1 → cinga.rule.completed
rule.failed.v1 → cinga.rule.failed
action.execute.requested.v1 → cinga.action.requested
action.executed.v1 → cinga.action.executed
action.failed.v1 → cinga.action.failed

SLA (Service Level Agreement)

MetrikHedef
Event Processing Latency (p95)< 200ms
Event Publishing Latency (p95)< 50ms
Event Schema Validation Rate100%
Duplicate Event Rate< 0.01%
Lost Event Rate0% (Kafka replication)

Backward Compatibility

Event schema versioning: schema_version field'i kullanılır.

Mevcut: schema_version = 1

Breaking Change Yapılırsa:
├─ schema_version = 2
├─ Consumers: v1 ve v2 handle etmeli
└─ Deprecated: eski alanlar -> null veya default value

Compat Strategy:

  • Yeni alanlar: backward compat (consumer ignore edebilir)
  • Removed alanlar: new schema version required