This document formalizes the canonical mental model of FlexiRule as implemented in its source code. It serves as a machine-accurate conceptual map for developers and architects.
- Code Evidence:
flexirule/ruleflow/doctype/rule/rule.py(ClassRule) - Definition: The primary unit of logic definition. A persistent container for a directed graph of Actions, Trigger configurations, and metadata (priority, execution mode).
- Role in Execution Flow: Serves as the source of truth for the
RuleEngine. It is compiled into a runtime specification before execution. - Relationships: Contains multiple Actions; triggered by Triggers; executed by the Rule Engine.
- Code Evidence:
flexirule/ruleflow/core/coordinator.py(ClassRuleCoordinator) - Definition: A high-level dispatcher responsible for rule discovery, eligibility filtering, and lifecycle management (caching, re-entry guarding).
- Role in Execution Flow: The entry point for all Frappe-integrated events. It manages the Runtime Registry and ensures rules only run when appropriate.
- Relationships: Dispatches execution to the Rule Engine; interfaces with Frappe Hooks.
- Code Evidence:
flexirule/ruleflow/core/engine.py(ClassRuleEngine) - Definition: The graph-traversal runtime that manages the lifecycle of a single rule execution. It handles state management, error recovery, and action dispatching.
- Role in Execution Flow: Executes the compiled graph of Actions.
- Relationships: Initializes the Execution Context; invokes Action Handlers.
- Code Evidence:
flexirule/ruleflow/core/engine.py(RuleEngine._initialize_context),flexirule/ruleflow/core/context_manager.py(ClassContextManager) - Definition: A stateful dictionary containing the current document (
doc), previous state (old_doc), variables (vars), metadata (meta), and system proxies (frappe). - Role in Execution Flow: Serves as the shared memory for all nodes in an execution path.
- Relationships: Managed by the Rule Engine; mutated by Actions via the Context Manager.
- Code Evidence:
engine.py(RuleEngine._execute_graph) - Definition: The atomic invocation of an Action Handler with the current Execution Context. Each execution produces a result and determines the
next_idfor traversal.
- Code Evidence:
engine.py(RuleEngine._execute_graph) - Definition: A sequential, state-based iteration through the action graph. The engine follows a single pointer (
current) through nodes until a terminal state or dead end is reached.
- Code Evidence:
contracts.py(TRIGGER_TYPE_CONTRACT),coordinator.py(execute_rules_from_event) - Source: Frappe Document Events (hooks).
- Execution Entry: Initiated by
flexirule.ruleflow.hooks.execute_rulesviadoc_events. - Payload: The active Frappe Document object (
doc) and its pre-save state (old_doc).
- Code Evidence:
rule_scheduler.py,scheduler.py - Source: Frappe Scheduler (
scheduler_events). - Execution Entry:
check_scheduled_rulesenqueuesrun_scheduled_rulefor dueRule Schedulerrecords. - Payload: A batch of document references identified by
filter_json.
- Code Evidence:
contracts.py,api.py(execute_rule) - Source: REST API, internal Python calls, or Sub-Rule actions.
- Execution Entry: Manual invocation via
RuleCoordinator.execute_rule. - Payload: Explicitly provided
varsand an optional document reference.
- Code Evidence:
rule_action.json,engine.py(_execute_graph) - Definition: A discrete node in the Rule graph representing a specific operation.
- Input Behavior: Configuration is stored as JSON in
configand resolved at runtime via the Value Resolver. - Output Behavior: Results are stored in
vars(viareturn_variable) or applied to thedoc(viamutation_mode). - Transaction Behavior: Actions can be wrapped in database savepoints. See
RuleEngine._execute_grapherror handling (Rollback mode).
- Code Evidence:
flexirule/ruleflow/core/action_handlers/(Abstract ClassActionHandler) - Definition: The Python implementation of an action type's logic.
- Implementation Location:
assignment.py,condition.py,create_doc.py,loop.py,process.py,query_records.py,simple_actions.py,sub_rule.py,switch.py.
- Code Evidence:
action_handlers/condition.py - Definition: A branching node that evaluates logic to determine whether to follow the
next_step_if_trueornext_step_if_falsepath.
- Code Evidence:
compiler.py(ClassConditionCompiler),runtime_eval.py - Definition: A two-stage system:
- Save-time: JSON logic trees are compiled into Python Boolean strings.
- Runtime: Compiled strings are evaluated via
frappe.safe_evalin a restricted context.
- Code Evidence:
compiler.py(_compile_group) - Definition: Recursive nesting of conditions using
and/oroperators.
- Code Evidence:
compiler.py(_compile_collection) - Definition: Logic that iterates over a collection (child table) to return a single Boolean based on whether
anyorallrows match a criteria.
- Code Evidence:
compiler.py,evaluator.py - Definition: Implemented via Python's native
and,or,any(), andall()in compiled expressions. In the legacyConditionEvaluator, it is NOT implemented (iterates all).
- Code Evidence:
engine.py(_initialize_context) - Structure: A dictionary with top-level keys:
doc,old_doc,vars,item,loop,frappe,meta,stop.
- Code Evidence:
value_resolver.py(get_context_value) - Namespaces:
doc: Access to Frappe Document fields.vars: Custom runtime variables.loop: Internal iteration state.
- Code Evidence:
context_manager.py(apply_mutation) - Modes:
Set Doc Field,Update Doc Field,Set Context Variable,Update Context Variable,Append to Context Variable,Batch Database Set.
- Code Evidence:
engine.py(_execute_graph) - Definition: Continuous passage of the
contextdictionary through successive action handler calls.
- Code Evidence:
RuleDocType (actionstable),graph_validator.py - Definition: A Directed Graph where nodes (Actions) are connected by directed edges (
next_step_if_true,next_step_if_false, orSwitchcases).
- Code Evidence:
engine.py(_execute_graph) - Strategy: Iterative pointer-following. It is a linear execution of a single path, not a branch-exploring traversal.
- Code Evidence:
action_handlers/loop.py - Definition: A non-recursive iteration mechanism. Each "iteration" of the
Loopaction handler advances an index invars._loops, executes thetruepath, and eventually exits via thefalsepath.
- Code Evidence:
action_handlers/sub_rule.py - Model: Synchronous, nested invocation of the
RuleEngine. Uses Sub-Rule Isolation (Overlay Context) to protect parent state.
- Save-time:
graph_validator.pyuses DFS with a recursion stack to block unintentional cycles. - Runtime:
RuleEnginemaintainsnode_visitscounts to prevent infinite loops (limit: 100).
- Code Evidence:
hooks.py - Definition: Global registration of
execute_ruleson all DocTypes (*).
- Code Evidence:
coordinator.py(_extract_watched_fields,_passes_watched_field_filter) - Definition: An optimization concept where a rule only executes if the fields changed in the document intersect with the fields it "watches" (derived from trigger conditions).
- Code Evidence:
scheduler.py,rule_scheduler.py - Definition: Integration with Frappe's
scheduler_eventsto trigger batch processing viaRule Schedulerrecords.
- Code Evidence:
flexirule/ruleflow/doctype/process/process.py - Definition: A metadata container for file-backed Python logic. Acts as a "Logic Provider" for the action system.
- Code Evidence:
coordinator.py(_build_runtime_registry) - Definition: A Redis-cached, compiled index of all active rules and their triggering metadata.
- Code Evidence:
engine.py(_save_execution_log),rule_execution_log/ - Definition: An asynchronous subsystem for persisting execution telemetry (path trace, context).
- Code Evidence:
rule.py(compile_conditions,compile_action_templates) - Definition: The set of methods that transform visual configuration (JSON) into optimized runtime artifacts (Python, Jinja).
- Code Evidence:
validation_service.py,graph_validator.py - Definition: A set of services that enforce structural and semantic integrity of Rules and Actions before they are permitted to activate.