{
  "rubric_id": "penjualan_kpi_v100",
  "effective_date": "2026-04-11",
  "score": {
    "max": 100,
    "pass_score": 100
  },
  "kpis": [
    {
      "id": "KPI-01",
      "name": "Critical Function Budget",
      "weight": 25,
      "rule": "100% fungsi kritikal harus <= max_loc"
    },
    {
      "id": "KPI-02",
      "name": "Typed Exception (Critical Path)",
      "weight": 20,
      "rule": "0 generic catch (except Exception / bare except) pada fungsi kritikal"
    },
    {
      "id": "KPI-03",
      "name": "Error Envelope Standard",
      "weight": 15,
      "rule": "Error wajib memiliki error_code, reason, trace_id"
    },
    {
      "id": "KPI-04",
      "name": "Enterprise Control Completeness",
      "weight": 20,
      "rule": "Idempotency, immutable audit log, approval trail, reconciliation wajib aktif"
    },
    {
      "id": "KPI-05",
      "name": "Test Maturity (Save/Load/Outbox)",
      "weight": 10,
      "rule": "Jumlah skenario uji branch/retry/chaos memenuhi ambang minimum"
    },
    {
      "id": "KPI-06",
      "name": "CI Quality Gate Lock",
      "weight": 10,
      "rule": "CI wajib fail jika skor KPI < pass_score"
    }
  ],
  "critical_functions": [
    {
      "file_path": "pypos/modules/penjualan/models/transaksi_model.py",
      "class_name": "TransaksiModel",
      "function_name": "simpan_transaksi",
      "max_loc": 50
    },
    {
      "file_path": "pypos/modules/penjualan/services/transaksi_persist_flow_service.py",
      "class_name": "TransaksiPersistFlowService",
      "function_name": "persist",
      "max_loc": 50
    },
    {
      "file_path": "pypos/modules/penjualan/services/transaksi_persist_flow_service.py",
      "class_name": "TransaksiPersistFlowService",
      "function_name": "_save_with_error_mapping",
      "max_loc": 50
    },
    {
      "file_path": "pypos/modules/penjualan/controllers/transaksi_penjualan_controller.py",
      "class_name": "TransaksiPenjualanController",
      "function_name": "_persist_transaksi_with_payment",
      "max_loc": 50
    },
    {
      "file_path": "pypos/modules/penjualan/controllers/load_transaksi_controller.py",
      "class_name": "LoadTransaksiController",
      "function_name": "load_dipilih",
      "max_loc": 50
    },
    {
      "file_path": "pypos/modules/penjualan/services/free_produk_sync_outbox_service.py",
      "class_name": "FreeProdukSyncOutboxService",
      "function_name": "claim_due_payloads",
      "max_loc": 50
    },
    {
      "file_path": "pypos/modules/penjualan/services/transaksi_simpan_use_case_service.py",
      "class_name": "TransaksiSimpanUseCaseService",
      "function_name": "execute",
      "max_loc": 70
    },
    {
      "file_path": "pypos/modules/penjualan/controllers/transaksi_penjualan_controller.py",
      "class_name": "TransaksiPenjualanController",
      "function_name": "_handle_persist_error",
      "max_loc": 30
    },
    {
      "file_path": "pypos/modules/penjualan/models/settlement_model.py",
      "class_name": "SettlementModel",
      "function_name": "simpan_settlement",
      "max_loc": 155
    },
    {
      "file_path": "pypos/modules/penjualan/models/settlement_model.py",
      "class_name": "SettlementModel",
      "function_name": "set_settlement",
      "max_loc": 210
    },
    {
      "file_path": "pypos/modules/penjualan/models/settlement_model.py",
      "class_name": "SettlementModel",
      "function_name": "execute_settlement_atomic",
      "max_loc": 165
    },
    {
      "file_path": "pypos/modules/penjualan/models/return_model.py",
      "class_name": "ReturnModel",
      "function_name": "insert_return",
      "max_loc": 150
    },
    {
      "file_path": "pypos/modules/penjualan/controllers/return_controller.py",
      "class_name": "ReturnController",
      "function_name": "proses_return",
      "max_loc": 105
    },
    {
      "file_path": "pypos/modules/penjualan/services/settlement_orchestrator_service.py",
      "class_name": "SettlementOrchestratorService",
      "function_name": "execute_settlement",
      "max_loc": 185
    }
  ],
  "critical_exception_targets": [
    {
      "file_path": "pypos/modules/penjualan/models/transaksi_model.py",
      "class_name": "TransaksiModel",
      "function_name": "simpan_transaksi"
    },
    {
      "file_path": "pypos/modules/penjualan/services/transaksi_persist_flow_service.py",
      "class_name": "TransaksiPersistFlowService",
      "function_name": "persist"
    },
    {
      "file_path": "pypos/modules/penjualan/services/transaksi_persist_flow_service.py",
      "class_name": "TransaksiPersistFlowService",
      "function_name": "_save_with_error_mapping"
    },
    {
      "file_path": "pypos/modules/penjualan/controllers/transaksi_penjualan_controller.py",
      "class_name": "TransaksiPenjualanController",
      "function_name": "_persist_transaksi_with_payment"
    },
    {
      "file_path": "pypos/modules/penjualan/controllers/load_transaksi_controller.py",
      "class_name": "LoadTransaksiController",
      "function_name": "load_dipilih"
    },
    {
      "file_path": "pypos/modules/penjualan/services/free_produk_sync_outbox_service.py",
      "class_name": "FreeProdukSyncOutboxService",
      "function_name": "claim_due_payloads"
    },
    {
      "file_path": "pypos/modules/penjualan/services/transaksi_simpan_use_case_service.py",
      "class_name": "TransaksiSimpanUseCaseService",
      "function_name": "execute"
    },
    {
      "file_path": "pypos/modules/penjualan/models/settlement_model.py",
      "class_name": "SettlementModel",
      "function_name": "simpan_settlement"
    },
    {
      "file_path": "pypos/modules/penjualan/models/settlement_model.py",
      "class_name": "SettlementModel",
      "function_name": "set_settlement"
    },
    {
      "file_path": "pypos/modules/penjualan/models/settlement_model.py",
      "class_name": "SettlementModel",
      "function_name": "execute_settlement_atomic"
    },
    {
      "file_path": "pypos/modules/penjualan/models/return_model.py",
      "class_name": "ReturnModel",
      "function_name": "insert_return"
    },
    {
      "file_path": "pypos/modules/penjualan/controllers/return_controller.py",
      "class_name": "ReturnController",
      "function_name": "proses_return"
    },
    {
      "file_path": "pypos/modules/penjualan/services/settlement_orchestrator_service.py",
      "class_name": "SettlementOrchestratorService",
      "function_name": "execute_settlement"
    }
  ],
  "required_markers": [
    "critical_flow",
    "retry",
    "chaos",
    "enterprise"
  ],
  "test_matrix": {
    "save_flow": {
      "files": [
        "tests/test_transaksi_persist_flow_service.py",
        "tests/test_transaksi_penjualan_controller_save_error_handling.py"
      ],
      "min_cases": 8
    },
    "load_flow": {
      "files": [
        "tests/test_load_transaksi_controller_load_flow.py",
        "tests/test_load_transaksi_controller_delete_guard.py"
      ],
      "min_cases": 4
    },
    "outbox_flow": {
      "files": [
        "tests/test_free_produk_sync_outbox_service.py",
        "tests/p1/test_transaksi_async_payload_guards.py"
      ],
      "min_cases": 10
    },
    "enterprise_flow": {
      "files": [
        "tests/test_transaksi_enterprise_control_service.py"
      ],
      "min_cases": 8
    },
    "retry_cases": {
      "files": [
        "tests/test_free_produk_sync_outbox_service.py",
        "tests/test_transaksi_persist_flow_service.py"
      ],
      "name_contains_any": [
        "retry",
        "idempotency"
      ],
      "min_cases": 4
    },
    "chaos_cases": {
      "files": [
        "tests/test_free_produk_sync_outbox_service.py",
        "tests/test_transaksi_enterprise_control_service.py"
      ],
      "name_contains_any": [
        "chaos",
        "stale",
        "immutable"
      ],
      "min_cases": 2
    }
  }
}
