Skip to main content

SLA Policy Evaluator System Behavior (Implemented)

Dokumen ini menjelaskan behavior runtime SLA Policy Evaluator yang sudah berjalan saat ini.

Komponen utama:

  • apps/worker-workflow/src/sla-policy-evaluator/services/cdc-forwarder/sla-cdc-forwarder.consumer.ts
  • apps/worker-workflow/src/sla-policy-evaluator/services/checker/sla-checker.service.ts
  • apps/worker-workflow/src/sla-policy-evaluator/services/schedule/sla-schedule.consumer.ts
  • apps/worker-workflow/src/sla-policy-evaluator/utils/sla-checker.utils.ts

1. Source of Truth dan Kontrak Event

Sumber event SLA:

  • Hanya dari CDC wxl_submission_log.

Payload transition yang dikirim ke checker:

  • submission_id
  • action_id
  • from_status_id
  • to_status_id
  • actor_user_id
  • changed_at
  • source_table = wxl_submission_log
  • submission_log_id (untuk dedupe; alias kompatibilitas: source_log_id)
  • source_lsn (metadata CDC)
  • submission_hint (snapshot ringan untuk troubleshooting)

Catatan:

  • Forwarder publish ke topic workflow.sla.check.on_transition.* (instant) jika changed_at <= now.
  • Forwarder publish ke topic workflow.sla.schedule.* jika changed_at > now, lalu dijalankan scheduler.
  • Checker tetap membaca wxl_submission terbaru dengan pessimistic_write.
  • submission_hint tidak dijadikan state final, hanya hint observability.

2. Flow Transition (Start/Resolve SLA)

Saat event transition diterima:

  1. Checker buka transaksi.
  2. Checker lock row wxl_submission.
  3. Checker resolve policy dari workflow_snapshot.slaPolicies atau fallback wml_sla_policy.
  4. Untuk tiap policy, checker jalankan guard idempotency.
  5. Checker tentukan apakah policy harus RESOLVE.
  6. Jika tidak resolve, checker evaluasi apakah policy harus START.

Behavior resolve:

  • Jika event.to_status_id == policy.resolve_status_id, seluruh instance open policy itu di-mark RESOLVED.
  • Log wxl_sla_log bertipe RESOLVED ditambahkan.

Behavior start:

  • Scope STATUS: start ketika event.to_status_id == policy.start_status_id.
  • Scope ACTION: wajib event dari submission log dan wajib ada action_id.
  • Jika condition_policy ada, dievaluasi sebagai SQL boolean.
  • Jika lolos, instance baru RUNNING dibuat dan due schedule dipublish.

3. Flow Aging Check (Breach vs Resolve)

Saat due event diproses:

  1. Checker lock wxl_sla_instance.
  2. Skip jika instance sudah RESOLVED atau BREACHED.
  3. Jika due_at belum lewat, instance di-reschedule.
  4. Jika due sudah lewat, checker tentukan apakah harus resolve atau breach.

Resolve guard saat due:

  • Guard A: jika submission.current_status_id saat ini sama dengan resolve_status_id, instance RESOLVED.
  • Guard B: jika current status sudah lewat, checker cari histori wxl_submission_log sejak instance.started_at (atau date_created).
  • Jika pernah ada to_status_id == resolve_status_id, instance tetap RESOLVED (tidak BREACHED).

Jika kedua guard tidak terpenuhi:

  • Instance di-mark BREACHED.
  • Log wxl_sla_log bertipe BREACHED ditambahkan.
  • Outcome policy dijalankan.

4. Behavior Condition Policy

Condition policy diproses sebagai SQL terparameter dengan konteks JSON.

Didukung:

  • Group nested: AND, OR, NOT.
  • Tipe rule: string, number, boolean, date, datetime.
  • Operator umum: eq, neq, in, not_in, contains, between, gt, gte, lt, lte, empty, not_empty.

Semantik:

  • Hasil akhir harus boolean (matched true/false).
  • Jika condition_policy kosong/null, default matched = true.
  • Modifier runtime juga didukung:
    • {"exclude_weekend": true} untuk skip Sabtu/Minggu pada kalkulasi due.
    • {"business_hours_only": true} sebagai fallback aktivasi business-hours jika is_use_business_hours belum diisi.

5. Native Business Hours / Weekend

Jika policy is_use_business_hours = true:

  • Due tidak dihitung 24/7, tetapi hanya di window UTC:
    • business_start_utc
    • business_end_utc
  • Hari kerja dapat diatur dengan working_days (contoh [1,2,3,4,5] untuk Senin-Jumat).
  • Default window jika null/invalid: 09:00:00 sampai 17:00:00 (UTC).
  • Jika is_exclude_weekend = true, Sabtu/Minggu tidak dihitung ke SLA timer.
  • condition_policy.exclude_weekend masih didukung sebagai fallback kompatibilitas.

Contoh konfigurasi:

  • Kolom policy:
    • is_use_business_hours = true
    • is_exclude_weekend = true
    • working_days = [1,2,3,4,5]
    • business_start_utc = '08:00:00'
    • business_end_utc = '17:00:00'
  • JSON condition:
    • { "exclude_weekend": true }

6. Idempotency dan Concurrency Guard

Guard yang aktif:

  • Dedupe event by submission_log_id per submission + policy.
  • No double start jika masih ada instance open pada policy yang sama.
  • Stale event guard: event lama diabaikan jika event.changed_at lebih tua dari update instance terakhir.
  • Seluruh operasi kritikal berjalan dalam transaksi DB.

7. Outcome Policy Behavior

Saat breach, outcome policy yang berjalan:

  • setStatusTo: mengubah wxl_sla_instance.sla_status (nilai valid: OK, BREACHED, PAUSED, dan alias BREACH -> BREACHED).
  • publishSubject: publish event SLA_BREACHED via JetStream, fallback ke core NATS jika publish gagal.

Catatan:

  • Outcome policy tidak mengubah wxl_submission.current_status_id.

8. Failure Handling

Forwarder/Scheduler/Checker behavior:

  • Payload invalid: di-drop + ack.
  • Error proses: nak agar bisa redelivery.
  • Scheduler melakukan delay dengan mekanisme nak(delay) sampai check_at.

9. Timeline Example (Kasus “Status Sudah Lewat”)

Contoh:

  • t0: log A -> B (policy start di B) => SLA RUNNING.
  • t+30m: log B -> C (policy resolve di C).
  • t+45m: log C -> D.
  • t+60m: aging dieksekusi.

Hasil:

  • Walau current status sudah D, checker tetap menemukan histori to_status_id = C setelah start.
  • Instance ditandai RESOLVED, bukan BREACHED.

10. Batasan Saat Ini

  • Dedupe kuat jika submission_log_id tersedia di event.
  • Behavior cross-workflow SLA agregasi kompleks belum jadi native flow khusus.