adjust ai insight and seed data
This commit is contained in:
1 parent
68e0d1a0bb
commit
a2b5b10977
18 files changed
+1835
-140
No files matched your search
@@ -0,0 +1,152 @@
|
||||
"""Unit tests for deterministic end-cycle root-cause candidates."""
|
||||
|
||||
from django.test import SimpleTestCase
|
||||
|
||||
from apps.operations.services import root_cause as rc
|
||||
|
||||
|
||||
class RootCauseHypothesisTests(SimpleTestCase):
|
||||
def test_early_mortality_plus_cold_hours_yields_brooding_suhu(self):
|
||||
graded = {
|
||||
"analyses": {
|
||||
"mortality": {
|
||||
"status": "critical",
|
||||
"severity_label": "SANGAT TINGGI",
|
||||
"actual_pct": 9.5,
|
||||
"message": "Mortalitas kumulatif 9.50% adalah SANGAT TINGGI",
|
||||
}
|
||||
}
|
||||
}
|
||||
context = {
|
||||
"weekly_summaries": [
|
||||
{
|
||||
"minggu_ke": 1,
|
||||
"mortalitas_delta_persen": 2.5,
|
||||
"jam_suhu_di_bawah_standar": 12,
|
||||
},
|
||||
{"minggu_ke": 2, "mortalitas_delta_persen": 1.2, "jam_suhu_di_bawah_standar": 6},
|
||||
]
|
||||
}
|
||||
hyps = rc.build_root_cause_hypotheses(graded, context)
|
||||
self.assertTrue(hyps)
|
||||
self.assertEqual(hyps[0]["id"], "brooding_suhu")
|
||||
self.assertEqual(hyps[0]["confidence"], "high")
|
||||
self.assertEqual(hyps[0]["fase"], "brooding")
|
||||
|
||||
def test_fcr_and_bw_lag_yields_pakan(self):
|
||||
graded = {
|
||||
"analyses": {
|
||||
"fcr": {"status": "critical", "message": "FCR di atas standar"},
|
||||
"bw": {
|
||||
"status": "warning",
|
||||
"direction": "di_bawah_standar",
|
||||
"message": "Bobot di bawah standar",
|
||||
},
|
||||
"mortality": {"status": "ok", "message": "Mortalitas normal"},
|
||||
}
|
||||
}
|
||||
hyps = rc.build_root_cause_hypotheses(graded, {})
|
||||
ids = [h["id"] for h in hyps]
|
||||
self.assertIn("pakan_akses", ids)
|
||||
|
||||
def test_high_mortality_alone_is_low_confidence_biosecurity(self):
|
||||
graded = {
|
||||
"analyses": {
|
||||
"mortality": {
|
||||
"status": "critical",
|
||||
"actual_pct": 9.49,
|
||||
"message": "Mortalitas kumulatif 9.49% adalah SANGAT TINGGI",
|
||||
}
|
||||
}
|
||||
}
|
||||
hyps = rc.build_root_cause_hypotheses(graded, {})
|
||||
self.assertEqual(len(hyps), 1)
|
||||
self.assertEqual(hyps[0]["id"], "penyakit_biosekuriti")
|
||||
self.assertEqual(hyps[0]["confidence"], "low")
|
||||
|
||||
|
||||
class NextCycleActionsTests(SimpleTestCase):
|
||||
def test_actions_map_from_top_hypotheses(self):
|
||||
hyps = [
|
||||
{
|
||||
"id": "brooding_suhu",
|
||||
"hipotesis": "Brooding / kontrol suhu",
|
||||
"confidence": "high",
|
||||
"fase": "brooding",
|
||||
"bukti": [],
|
||||
},
|
||||
{
|
||||
"id": "pakan_akses",
|
||||
"hipotesis": "Pakan / akses pakan",
|
||||
"confidence": "med",
|
||||
"fase": "growth",
|
||||
"bukti": [],
|
||||
},
|
||||
]
|
||||
actions = rc.build_next_cycle_actions(hyps)
|
||||
self.assertEqual(len(actions), 2)
|
||||
self.assertEqual(actions[0]["fase"], "brooding")
|
||||
self.assertIn("suhu", actions[0]["aksi"].lower())
|
||||
self.assertTrue(actions[0]["metrik_pantau"])
|
||||
|
||||
|
||||
class SanitizeEndCycleTests(SimpleTestCase):
|
||||
def test_drops_invented_causes(self):
|
||||
hyps = [
|
||||
{
|
||||
"id": "penyakit_biosekuriti",
|
||||
"hipotesis": "Penyakit / biosekuriti",
|
||||
"confidence": "low",
|
||||
"fase": "brooding",
|
||||
"bukti": ["mort high"],
|
||||
}
|
||||
]
|
||||
actions = rc.build_next_cycle_actions(hyps)
|
||||
parsed = {
|
||||
"kesimpulan": "Ada masalah mortalitas",
|
||||
"masalah": ["Mortalitas tinggi"],
|
||||
"akar_penyebab": [
|
||||
{"id": "alien_cause", "hipotesis": "Serangan alien", "bukti": ["X"]},
|
||||
{
|
||||
"id": "penyakit_biosekuriti",
|
||||
"hipotesis": "Penyakit / biosekuriti",
|
||||
"bukti": ["Nekropsi diperlukan"],
|
||||
},
|
||||
],
|
||||
"perbaikan_siklus_berikutnya": [
|
||||
{"id": "alien_cause", "fase": "brooding", "aksi": "Do nothing"},
|
||||
{
|
||||
"id": "penyakit_biosekuriti",
|
||||
"fase": "brooding",
|
||||
"aksi": "Perketat biosekuriti custom",
|
||||
"metrik_pantau": "mortalitas harian",
|
||||
},
|
||||
],
|
||||
"insight": "Fokus biosekuriti",
|
||||
}
|
||||
out = rc.sanitize_end_cycle_payload(
|
||||
parsed, hypotheses=hyps, actions=actions, masalah=["Mortalitas tinggi"]
|
||||
)
|
||||
ids = [a["id"] for a in out["akar_penyebab"]]
|
||||
self.assertEqual(ids, ["penyakit_biosekuriti"])
|
||||
self.assertNotIn("alien_cause", [p["id"] for p in out["perbaikan_siklus_berikutnya"]])
|
||||
self.assertIn("biosekuriti", out["perbaikan_siklus_berikutnya"][0]["aksi"].lower())
|
||||
|
||||
def test_format_embeds_json_marker(self):
|
||||
payload = rc.local_fallback_end_cycle(
|
||||
{
|
||||
"analyses": {
|
||||
"mortality": {
|
||||
"status": "critical",
|
||||
"actual_pct": 9.0,
|
||||
"message": "Mortalitas kritis",
|
||||
}
|
||||
}
|
||||
},
|
||||
{},
|
||||
)
|
||||
text = rc.format_end_cycle_insight_text(payload)
|
||||
self.assertIn(rc.END_CYCLE_JSON_MARKER, text)
|
||||
parsed = rc.parse_embedded_end_cycle(text)
|
||||
self.assertIsNotNone(parsed)
|
||||
self.assertEqual(parsed["kesimpulan"], payload["kesimpulan"])
|
||||
Reference in new issue
Block a user