{"id":19004853,"url":"https://github.com/dhis2/dhis2-rule-engine","last_synced_at":"2025-04-09T15:08:18.580Z","repository":{"id":40548398,"uuid":"111812461","full_name":"dhis2/dhis2-rule-engine","owner":"dhis2","description":"Rule engine library for DHIS 2","archived":false,"fork":false,"pushed_at":"2025-03-17T12:48:56.000Z","size":2127,"stargazers_count":10,"open_issues_count":2,"forks_count":16,"subscribers_count":33,"default_branch":"master","last_synced_at":"2025-04-09T15:08:13.133Z","etag":null,"topics":["engine","expressionengine","rule","team-android"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dhis2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-23T13:26:03.000Z","updated_at":"2025-03-17T12:40:06.000Z","dependencies_parsed_at":"2023-11-28T08:27:11.393Z","dependency_job_id":"e428437e-f574-442b-8486-0c7281f7f132","html_url":"https://github.com/dhis2/dhis2-rule-engine","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhis2%2Fdhis2-rule-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhis2%2Fdhis2-rule-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhis2%2Fdhis2-rule-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhis2%2Fdhis2-rule-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dhis2","download_url":"https://codeload.github.com/dhis2/dhis2-rule-engine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248055283,"owners_count":21040157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["engine","expressionengine","rule","team-android"],"created_at":"2024-11-08T18:24:51.886Z","updated_at":"2025-04-09T15:08:18.561Z","avatar_url":"https://github.com/dhis2.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.hisp.dhis.rules/rule-engine/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.hisp.dhis.rules/rule-engine)\n[![NPM Version](https://img.shields.io/npm/v/@dhis2/rule-engine)](https://www.npmjs.com/package/@dhis2/rule-engine)\n[![KDoc link](https://img.shields.io/badge/API_reference-KDoc-blue)](https://dhis2.github.io/dhis2-rule-engine/api/)\n\n### RuleEngine (WIP)\n\n#### Initialization\n`RuleEngine` is initialized in two steps.\n - Metadata configuration within `RuleEngineContext`\n - Setting background / contextual data for `RuleEngine`\n\n```\nRuleEngineContext ruleEngineContext = RuleEngineContext.builder(ruleExpressionEvaluator)\n                .ruleVariables(ruleVariables)    // optional\n                .rules(rules)                    // at least one rule must be supplied\n                .build();\n```\n\n`.builder` factory method accepts instance of `RuleExpressionEvaluator` - something what knows how to evaluate program rule statements. `RuleExpressionEvaluator` implementation might be specific to certain platform. For example, on JVM it can be backed by [JEXL](http://commons.apache.org/proper/commons-jexl/), while on android it can be something like [duktape-android](https://github.com/square/duktape-android.git).\n\n`RuleEngineContext` instance is immutable. It means it can be safely shared and reused across multiple threads. Next step will be setting some contextual data to the rule engine, which will be used as a source of data for most variables.\n\n```\nRuleEngine ruleEngine = ruleEngineContext.toEngineBuilder()\n        .enrollment(enrollment)    // contextual enrollment\n        .events(events)            // contextual events\n        .build();\n```\n\n`RuleEngine` is immutable as well. In example above, `toEngineBuilder()` method returns and instance of `RuleEngine.Builder` class. All parameters are optional, it means that one can simply call `ruleEngineContext.toEngineBuilder().build()` to get an instance of engine back.\n\n#### Evaluation\nNow we can send target event or enrollment to the engine in order to get some `RuleEffect`s back. Before showing code, there are certain quirks which one should be aware of. You are not allowed to send duplicate events or enrollments to the engine as evaluation targets. In other words, if you have already supplied enrollment or event as a part of the contextual data, you won't be allowed to send it again as evaluation target. For example:\n\n```\nRuleEngine ruleEngine = ruleEngineContext.toEngineBuilder()\n        .enrollment(enrollment)    // contextual enrollment        \n        .build();\n\nruleEngine.evaluate(enrollment);   // not allowed!        \n```\n\nIn general, there are a few scenarios in which rule engine can be used. Let's use next notation to declare possible options.\n\n`\u003cmetadata\u003e(contextual_data)[evaluation_target]`\n\n- `\u003crules, variables\u003e(single_events - target_event)[target_event]`: applicable for programs without registration.\n- `\u003crules, variables\u003e(enrollment, enrollment_events - target_event)[target_event]`: applicable for programs with registration. In this case, event is under evaluation.\n- `\u003crules, variables\u003e(enrollment_events)[target_enrollment]`: evaluating enrollment. In this case, events which are a part of enrollment, can be used as source of values for program rule variables.  \n\nThere are two methods for evaluation at the moment:\n```\nList\u003cRuleEffect\u003e enrollmentEffects = ruleEngine.evaluate(enrollment);\nList\u003cRuleEffect\u003e eventEffects = ruleEngine.evaluate(event);\n```\n\nList of supported environment (contextual) variables:\n - current_date\n - event_date\n - event_count\n - due_date\n - event_id\n - enrollment_date\n - enrollment_id\n - enrollment_count\n - incident_date\n - tei_count\n\n## Development\n\n### API Validator\nThis library uses the [Binary Compatibility Validator plugin](https://github.com/Kotlin/binary-compatibility-validator), which verifies that there are no changes in the public API of the library.\n\nThe way of work is: there is a file generated by the plugin (`api/expression-parser.api`) with the binary representation of the expected public API. The plugin has a task (`apiCheck`) that verifies that the public API of the code matches the expected API in the file.\n\nIf there is an intentional change in the public API, this file must be updated to reflect the changes and included as part of the pull request. It can be updated running the task `apiDump`. This task can be run in the command line (`./gradlew apiDump`) or using Gradle window in Intellij.\n\n### Version\nLibrary version is defined in the file `build.gradle.kts`. The version must be manually increased\nand include the `-SNAPSHOT` suffix. Please make sure the version is updated before opening the PR.\n\n### Publications\n\nOn merged pull request to `main`:\n- Production release to Maven.\n- Production release to NPMJS.\n\nOn pull request creation/update:\n- Snapshot release to Maven.\n\nOn demand:\n- Beta releases to NPMJS can be triggered on demand by using the action \"Publish NPM beta\".\n  Please make sure you select the right branch in the selector.\n\nPublication can be skipped by adding `[skip publish]` to the pull request title.\n\n---\nWIP\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhis2%2Fdhis2-rule-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdhis2%2Fdhis2-rule-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhis2%2Fdhis2-rule-engine/lists"}