Walks a decision tree from START and renders, per outcome, the
chain of conditions that lead to it. Operators are highlighted so
the logic is easy to scan.
DecisionRules — set as ReportType in def_report.
def Render(self, Param1="", Param2="", Param3="") -> str:
Param1 — DecisionName.Param2 — optional outcome filter (e.g. O27).Param3 — optional Version (defaults to MAX(Version)).The standalone URL is
/report/decision_rules/<DecisionName>[/<outcome>[/<version>]].
import ObjReportDecisionRules
rules = ObjReportDecisionRules.Report(self.DB)
# Live HTML page — uncapped row count
html = rules.render_fragment(
decision_name="hc_col_bl_v1",
version=0, # 0 = use MAX(Version)
outcome="", # empty = all outcomes
max_paths=5, # cap paths shown per outcome
max_depth=50, # safety cap on DFS depth
)
# Email fragment — capped at 50 outcome rows for deliverability
email_html = rules.render_email_fragment(
decision_name="hc_col_bl_v1",
palette=palette,
sim_table=sim_table,
max_paths=2, # cap paths shown per outcome
max_rows=50, # cap total outcomes rendered
)
render_email_fragment accepts max_rows (default 50). Outcomes are
ranked by descending sim count when a sim_table is supplied (true
"top N"); without counts they fall back to alphabetic order. When
the cap truncates the table, a footer row notes how many outcomes
were omitted. The cap applies only to the email path —
render_fragment (the live HTML page) stays uncapped.
(DecisionName, Version) fromdef_decision_treenodes, ordered by Guid then rank.START, treatingGuid starts with O as a terminal outcome.field <op> value, with operators (<, >=, in, to,Between, ELSE, AND) highlighted via .rule-op.Between (a,b) renders as field in a to b.in (a,b,c) renders as field in [a, b, c].condition_field='ELSE' renders as the ELSE operator badge,