From cf458536fbe7b57485d2d018a068ebf03fb53357 Mon Sep 17 00:00:00 2001 From: Syed Waseem Date: Tue, 25 Aug 2026 12:50:16 +0530 Subject: [PATCH] feat: implement policy applicability and rule evaluation services for policy engine engine --- .../services/policy-applicability.service.ts | 14 ++++++++++++++ .../services/rule-evaluation.service.ts | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/modules/policy-engine/services/policy-applicability.service.ts b/src/modules/policy-engine/services/policy-applicability.service.ts index 390c19d..c7b1acb 100644 --- a/src/modules/policy-engine/services/policy-applicability.service.ts +++ b/src/modules/policy-engine/services/policy-applicability.service.ts @@ -51,6 +51,20 @@ export class PolicyApplicabilityService { const matchedCohortIds = new Set(matchedCohorts.map((c) => c.cohortId)); const applicable = activePolicies.filter((policy) => { + // 0. Valid Rule & Condition Requirement Check + const rules = policy.rules || []; + const hasConfiguredConditions = rules.some((rule) => { + const conds = rule.conditions || []; + return conds.some((c) => Boolean(c.fieldId || (c as any).condition)); + }); + + if (!hasConfiguredConditions) { + this.logger.warn( + `[POLICY REJECTED ❌] Policy "${policy.policyName}" (ID: ${policy.id}) contains no configured rule conditions or evaluation criteria.`, + ); + return false; + } + // 1. Jurisdiction Match const incidentJurisdiction = ctx.jurisdictionId || ctx.jurisdictionCode; const policyJurisdictions = policy.jurisdictions || []; diff --git a/src/modules/policy-engine/services/rule-evaluation.service.ts b/src/modules/policy-engine/services/rule-evaluation.service.ts index 504ce0f..c1430b1 100644 --- a/src/modules/policy-engine/services/rule-evaluation.service.ts +++ b/src/modules/policy-engine/services/rule-evaluation.service.ts @@ -51,14 +51,16 @@ export class RuleEvaluationService { ); if (sortedConditions.length === 0) { - this.logger.log(`>>> [RULE MATCHED ✅] Rule ID: ${rule.id} (Priority: ${rule.priority}) | Reason: No conditions defined (unconditional rule).`); + this.logger.warn( + `>>> [RULE NOT MATCHED ❌] Rule ID: ${rule.id} (Priority: ${rule.priority}) | Reason: No conditions configured for rule.`, + ); return { ruleId: rule.id, category: rule.ruleCategoryId, priority: rule.priority || 1, - matched: true, + matched: false, conditions: [], - reason: 'Unconditional rule automatically matched.', + reason: 'Rule has no configured conditions or evaluation criteria.', }; }