{
  "schema_version": 2,
  "meta": {
    "title": "Collection Queue Builder",
    "description": "Filters and scores overdue contracts to build a prioritized collection queue for today's dialing run.",
    "source_type": "code",
    "data_origin": "synthetic",
    "entity_schema": {
      "id": "integer",
      "status": "string",
      "in_legal_dispute": "boolean",
      "days_overdue": "integer",
      "balance": "number"
    },
    "rule_source": "src/billing/collection-queue.js",
    "generated_at": "2026-07-23T12:00:00Z"
  },
  "initial_dataset": {
    "count": 16,
    "sample": [
      { "id": 1,  "status": "overdue",      "in_legal_dispute": false, "days_overdue": 45, "balance": 3200.00 },
      { "id": 2,  "status": "overdue",      "in_legal_dispute": false, "days_overdue": 22, "balance": 1800.00 },
      { "id": 3,  "status": "paid",         "in_legal_dispute": false, "days_overdue": 0,  "balance": 0.00   },
      { "id": 4,  "status": "overdue",      "in_legal_dispute": true,  "days_overdue": 60, "balance": 15000.00 },
      { "id": 5,  "status": "overdue",      "in_legal_dispute": false, "days_overdue": 3,  "balance": 500.00  },
      { "id": 6,  "status": "overdue",      "in_legal_dispute": false, "days_overdue": 38, "balance": 4100.00 },
      { "id": 7,  "status": "active",       "in_legal_dispute": false, "days_overdue": 0,  "balance": 1200.00 },
      { "id": 8,  "status": "overdue",      "in_legal_dispute": false, "days_overdue": 12, "balance": 800.00  },
      { "id": 9,  "status": "overdue",      "in_legal_dispute": true,  "days_overdue": 90, "balance": 8000.00 },
      { "id": 10, "status": "overdue",      "in_legal_dispute": false, "days_overdue": 55, "balance": 6000.00 },
      { "id": 11, "status": "renegotiated", "in_legal_dispute": false, "days_overdue": 0,  "balance": 2000.00 },
      { "id": 12, "status": "overdue",      "in_legal_dispute": false, "days_overdue": 28, "balance": 2400.00 },
      { "id": 13, "status": "overdue",      "in_legal_dispute": false, "days_overdue": 4,  "balance": 3000.00 },
      { "id": 14, "status": "overdue",      "in_legal_dispute": false, "days_overdue": 67, "balance": 5500.00 },
      { "id": 15, "status": "overdue",      "in_legal_dispute": false, "days_overdue": 8,  "balance": 1100.00 },
      { "id": 16, "status": "overdue",      "in_legal_dispute": false, "days_overdue": 41, "balance": 7200.00 }
    ],
    "note": "Synthetic dataset. entity_schema reflects only fields observed in buildCollectionQueue() — the actual entity may have additional fields."
  },
  "steps": [
    {
      "step_type": "filter",
      "id": "step-1",
      "name": "Filter actionable contracts",
      "rule_text": "Keeps contracts where status is 'overdue', in_legal_dispute is false, and days_overdue is at least 5.",
      "condition_expr": "c.status === 'overdue' && !c.in_legal_dispute && c.days_overdue >= 5",
      "confidence": "assumed",
      "confidence_note": "The threshold of 5 days (days_overdue >= 5) is a magic number with no comment or configuration reference in the source code.",
      "input_count": 16,
      "output_count": 9,
      "passed_sample": [
        { "id": 1,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 45, "balance": 3200.00 },
        { "id": 2,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 22, "balance": 1800.00 },
        { "id": 6,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 38, "balance": 4100.00 },
        { "id": 8,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 12, "balance": 800.00  },
        { "id": 10, "status": "overdue", "in_legal_dispute": false, "days_overdue": 55, "balance": 6000.00 },
        { "id": 12, "status": "overdue", "in_legal_dispute": false, "days_overdue": 28, "balance": 2400.00 },
        { "id": 14, "status": "overdue", "in_legal_dispute": false, "days_overdue": 67, "balance": 5500.00 },
        { "id": 15, "status": "overdue", "in_legal_dispute": false, "days_overdue": 8,  "balance": 1100.00 },
        { "id": 16, "status": "overdue", "in_legal_dispute": false, "days_overdue": 41, "balance": 7200.00 }
      ],
      "rejected_sample": [
        { "record": { "id": 3,  "status": "paid",         "in_legal_dispute": false, "days_overdue": 0,  "balance": 0.00     }, "reason": "status is 'paid', not 'overdue'" },
        { "record": { "id": 4,  "status": "overdue",      "in_legal_dispute": true,  "days_overdue": 60, "balance": 15000.00 }, "reason": "in_legal_dispute is true" },
        { "record": { "id": 5,  "status": "overdue",      "in_legal_dispute": false, "days_overdue": 3,  "balance": 500.00   }, "reason": "days_overdue (3) < 5" },
        { "record": { "id": 7,  "status": "active",       "in_legal_dispute": false, "days_overdue": 0,  "balance": 1200.00  }, "reason": "status is 'active', not 'overdue'" },
        { "record": { "id": 9,  "status": "overdue",      "in_legal_dispute": true,  "days_overdue": 90, "balance": 8000.00  }, "reason": "in_legal_dispute is true" },
        { "record": { "id": 11, "status": "renegotiated", "in_legal_dispute": false, "days_overdue": 0,  "balance": 2000.00  }, "reason": "status is 'renegotiated', not 'overdue'" },
        { "record": { "id": 13, "status": "overdue",      "in_legal_dispute": false, "days_overdue": 4,  "balance": 3000.00  }, "reason": "days_overdue (4) < 5" }
      ]
    },
    {
      "step_type": "transform",
      "id": "step-2",
      "name": "Calculate risk score",
      "rule_text": "Adds a risk_score field: days_overdue * 1.2 + balance / 200, rounded to integer.",
      "condition_expr": "risk_score = Math.round(c.days_overdue * 1.2 + c.balance / 200)",
      "confidence": "assumed",
      "confidence_note": "Both coefficients (multiplier 1.2 and divisor 200) are magic numbers with no comment or configuration reference.",
      "input_count": 9,
      "output_count": 9,
      "changes": ["risk_score added"],
      "output_sample": [
        { "id": 1,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 45, "balance": 3200.00, "risk_score": 70  },
        { "id": 2,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 22, "balance": 1800.00, "risk_score": 35  },
        { "id": 6,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 38, "balance": 4100.00, "risk_score": 66  },
        { "id": 8,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 12, "balance": 800.00,  "risk_score": 18  },
        { "id": 10, "status": "overdue", "in_legal_dispute": false, "days_overdue": 55, "balance": 6000.00, "risk_score": 96  },
        { "id": 12, "status": "overdue", "in_legal_dispute": false, "days_overdue": 28, "balance": 2400.00, "risk_score": 46  },
        { "id": 14, "status": "overdue", "in_legal_dispute": false, "days_overdue": 67, "balance": 5500.00, "risk_score": 108 },
        { "id": 15, "status": "overdue", "in_legal_dispute": false, "days_overdue": 8,  "balance": 1100.00, "risk_score": 15  },
        { "id": 16, "status": "overdue", "in_legal_dispute": false, "days_overdue": 41, "balance": 7200.00, "risk_score": 85  }
      ]
    },
    {
      "step_type": "filter",
      "id": "step-3",
      "name": "Keep high-risk contracts only",
      "rule_text": "Keeps only contracts whose risk_score is 50 or higher.",
      "condition_expr": "c.risk_score >= 50",
      "confidence": "assumed",
      "confidence_note": "The threshold of 50 is a magic number with no comment or configuration reference in the source code.",
      "input_count": 9,
      "output_count": 5,
      "passed_sample": [
        { "id": 1,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 45, "balance": 3200.00, "risk_score": 70  },
        { "id": 6,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 38, "balance": 4100.00, "risk_score": 66  },
        { "id": 10, "status": "overdue", "in_legal_dispute": false, "days_overdue": 55, "balance": 6000.00, "risk_score": 96  },
        { "id": 14, "status": "overdue", "in_legal_dispute": false, "days_overdue": 67, "balance": 5500.00, "risk_score": 108 },
        { "id": 16, "status": "overdue", "in_legal_dispute": false, "days_overdue": 41, "balance": 7200.00, "risk_score": 85  }
      ],
      "rejected_sample": [
        { "record": { "id": 2,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 22, "balance": 1800.00, "risk_score": 35  }, "reason": "risk_score (35) < 50" },
        { "record": { "id": 8,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 12, "balance": 800.00,  "risk_score": 18  }, "reason": "risk_score (18) < 50" },
        { "record": { "id": 12, "status": "overdue", "in_legal_dispute": false, "days_overdue": 28, "balance": 2400.00, "risk_score": 46  }, "reason": "risk_score (46) < 50" },
        { "record": { "id": 15, "status": "overdue", "in_legal_dispute": false, "days_overdue": 8,  "balance": 1100.00, "risk_score": 15  }, "reason": "risk_score (15) < 50" }
      ]
    }
  ],
  "final_result": {
    "count": 5,
    "sample": [
      { "id": 1,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 45, "balance": 3200.00, "risk_score": 70  },
      { "id": 6,  "status": "overdue", "in_legal_dispute": false, "days_overdue": 38, "balance": 4100.00, "risk_score": 66  },
      { "id": 10, "status": "overdue", "in_legal_dispute": false, "days_overdue": 55, "balance": 6000.00, "risk_score": 96  },
      { "id": 14, "status": "overdue", "in_legal_dispute": false, "days_overdue": 67, "balance": 5500.00, "risk_score": 108 },
      { "id": 16, "status": "overdue", "in_legal_dispute": false, "days_overdue": 41, "balance": 7200.00, "risk_score": 85  }
    ]
  }
}
