Skip to content

Commit b0ca3bf

Browse files
committed
Update from the latest changes to FUNCTIONS.md in circulation.
1 parent f3b6a85 commit b0ca3bf

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

src/content/patronBlockingFunctionsHtml.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
// Run `npm run sync-patron-blocking-docs` to regenerate from
33
// circulation/docs/FUNCTIONS.md.
44
const patronBlockingFunctionsHtml =
5-
'<h1>Patron Blocking Rules — Allowed Functions</h1>\n<p>Patron blocking rule expressions are evaluated by a locked-down <a href="https://github.com/danthedeckie/simpleeval">simpleeval</a> sandbox. Only the functions listed below may be called inside a rule expression. Any reference to an unlisted function causes the rule to <strong>fail open</strong> (the patron is not blocked at runtime; the rule is accepted at admin-save time, though there is feedback in the Admin UI warning the user that there is a problem with the rule).</p>\n<hr>\n<h2><code>age_in_years</code></h2>\n<p>Calculates the age of a person in <strong>whole years</strong> from a date string. Use this to write rules that gate access by age (e.g. block minors or enforce senior-only services).</p>\n<h3>Signature</h3>\n<pre><code class="language-text">age_in_years(date_str, fmt=None) -&gt; int</code></pre>\n<h3>Parameters</h3>\n<table class="table table-condensed table-bordered"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th></tr></thead><tbody><tr><td><code>date_str</code></td><td><code>str</code></td><td>Yes</td></tr>\n<tr><td><code>fmt</code></td><td><code>str</code> or <code>None</code></td><td>No</td></tr></tbody></table>\n<ul>\n<li><strong><code>date_str</code></strong> — A date string representing the person\'s date of birth.</li>\n</ul>\n<p> ISO 8601 format (<code>YYYY-MM-DD</code>) is tried first; if that fails, <code>dateutil.parser</code> is used as a fallback, accepting most common human-readable formats (e.g. <code>&quot;Jan 1, 1990&quot;</code>, <code>&quot;01/01/1990&quot;</code>). - <strong><code>fmt</code></strong> — An explicit <a href="https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime"><code>strptime</code></a> format string (e.g. <code>&quot;%d/%m/%Y&quot;</code>). When supplied, no automatic parsing is attempted.</p>\n<h3>Returns</h3>\n<p><code>int</code> — The person\'s age in complete years (fractional years are truncated, not rounded).</p>\n<h3>Raises</h3>\n<p><code>ValueError</code> — If <code>date_str</code> cannot be parsed (either by ISO 8601, the supplied <code>fmt</code>, or <code>dateutil</code>). At runtime this causes the rule to <strong>fail open</strong>.</p>\n<h3>Examples</h3>\n<pre><code class="language-python"># Block patrons under 18 (field returned verbatim from the SIP2 server)\nage_in_years({polaris_patron_birthdate}) &lt; 18\n\n# Block patrons under 18 using an explicit strptime format\nage_in_years({dob_field}, &quot;%d/%m/%Y&quot;) &lt; 18\n\n# Block patrons aged 65 or over (e.g. senior-only restriction)\nage_in_years({polaris_patron_birthdate}) &gt;= 65</code></pre>\n<hr>\n<h2><code>int</code></h2>\n<p>Converts a value to a Python <code>int</code>. Useful when the SIP2 server returns a numeric field as a string (a common occurrence) and you need to compare it numerically rather than lexicographically.</p>\n<h3>Signature</h3>\n<pre><code class="language-text">int(value) -&gt; int</code></pre>\n<h3>Parameters</h3>\n<table class="table table-condensed table-bordered"><thead><tr><th>Parameter</th><th>Type</th><th>Required</th></tr></thead><tbody><tr><td><code>value</code></td><td><code>Any</code></td><td>Yes</td></tr></tbody></table>\n<ul>\n<li><strong><code>value</code></strong> — The value to convert. Typically a string such as <code>&quot;3&quot;</code> or</li>\n</ul>\n<p> a float such as <code>2.9</code>. Any value accepted by Python\'s built-in <code>int()</code> is valid. Passing a non-numeric string (e.g. <code>&quot;adult&quot;</code>) raises a <code>ValueError</code> and causes the rule to <strong>fail open</strong>.</p>\n<h3>Returns</h3>\n<p><code>int</code> — The integer representation of <code>value</code>. Floating-point values are <strong>truncated</strong> toward zero (e.g. <code>int(&quot;2.9&quot;)</code> raises <code>ValueError</code>; pass a float literal or cast via <code>{field} * 1</code> first if you need truncation of floats).</p>\n<h3>Raises</h3>\n<p><code>ValueError</code> — If <code>value</code> cannot be converted to an integer. At runtime this causes the rule to <strong>fail open</strong>.</p>\n<h3>Examples</h3>\n<pre><code class="language-python"># Block patron class codes above 2 (SIP2 returns the code as a string)\nint({sipserver_patron_class}) &gt; 2\n\n# Block if a numeric expiry-year field indicates an expired account\nint({expire_year}) &lt; 2025</code></pre>\n<hr>\n<h2>Notes</h2>\n<ul>\n<li><strong>String methods are available</strong> — methods on Python <code>str</code> values can be</li>\n</ul>\n<p> called directly on string-valued placeholders. For example, to check whether a patron identifier starts with a certain prefix:</p>\n<p> ``<code>python {patron_identifier}.startswith(&quot;1234&quot;) </code>``</p>\n<ul>\n<li><strong>Fail-open behaviour</strong> — any function call that raises an exception</li>\n</ul>\n<p> (e.g. an unparseable date or a non-numeric string passed to <code>int()</code>) causes the rule to be <strong>skipped</strong> at runtime (the patron is not blocked by that rule) and the rule to be <strong>accepted</strong> at admin-save time (with a warning in the Admin UI that there is a problem with the rule). Write test rules carefully using representative patron data before enabling them in production. - <strong>No other builtins</strong> — Python builtins such as <code>len</code>, <code>str</code>, <code>float</code>, <code>abs</code>, and <code>round</code> are <strong>not</strong> available. If you need additional functions, request them via the standard feature-request process so they can be reviewed and added to <code>DEFAULT_ALLOWED_FUNCTIONS</code> in <code>rule_engine.py</code>. - <strong>Placeholder syntax</strong> — field values from the SIP2 response are referenced as <code>{field_name}</code>. All fields returned by the SIP2 <code>patron_information</code> command are available, plus the normalised <code>{fines}</code> key (a <code>float</code> derived from <code>fee_amount</code>).</p>';
5+
'<h1>Patron Blocking Rules — Allowed Functions</h1>\n<p>Patron blocking rule expressions are evaluated by a locked-down\n<a href="https://github.com/danthedeckie/simpleeval">simpleeval</a> sandbox.\nOnly the functions listed below may be called inside a rule expression.\nAny reference to an unlisted function causes the rule to <strong>fail open</strong>\n(the patron is not blocked at runtime; the rule is accepted at admin-save time,\nthough there is feedback in the Admin UI warning the user that there is a problem\nwith the rule).</p>\n<hr>\n<h2><code>age_in_years</code></h2>\n<p>Calculates the age of a person in <strong>whole years</strong> from a date string.\nUse this to write rules that gate access by age (e.g. block minors or\nenforce senior-only services).</p>\n<h3>Signature</h3>\n<pre><code class="language-text">age_in_years(date_str, fmt=None) -&gt; int\n</code></pre>\n<h3>Parameters</h3>\n<table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>date_str</code></td>\n<td><code>str</code></td>\n<td>Yes</td>\n</tr>\n<tr>\n<td><code>fmt</code></td>\n<td><code>str</code> or <code>None</code></td>\n<td>No</td>\n</tr>\n</tbody></table>\n<ul>\n<li><strong><code>date_str</code></strong> — A date string representing the person&#39;s date of birth.\nISO 8601 format (<code>YYYY-MM-DD</code>) is tried first; if that fails,\n<code>dateutil.parser</code> is used as a fallback, accepting most common\nhuman-readable formats (e.g. <code>&quot;Jan 1, 1990&quot;</code>, <code>&quot;01/01/1990&quot;</code>).</li>\n<li><strong><code>fmt</code></strong> — An explicit\n<a href="https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime"><code>strptime</code></a>\nformat string (e.g. <code>&quot;%d/%m/%Y&quot;</code>). When supplied, no automatic parsing\nis attempted.</li>\n</ul>\n<h3>Returns</h3>\n<p><code>int</code> — The person&#39;s age in complete years (fractional years are truncated,\nnot rounded).</p>\n<h3>Raises</h3>\n<p><code>ValueError</code> — If <code>date_str</code> cannot be parsed (either by ISO 8601, the\nsupplied <code>fmt</code>, or <code>dateutil</code>). At runtime this causes the rule to\n<strong>fail open</strong>.</p>\n<h3>Examples</h3>\n<pre><code class="language-python"># Block patrons under 18 (field returned verbatim from the remote patron_information call)\nage_in_years({polaris_patron_birthdate}) &lt; 18\n\n# Block patrons under 18 using an explicit strptime format\nage_in_years({dob_field}, &quot;%d/%m/%Y&quot;) &lt; 18\n\n# Block patrons aged 65 or over (e.g. senior-only restriction)\nage_in_years({polaris_patron_birthdate}) &gt;= 65\n</code></pre>\n<hr>\n<h2><code>int</code></h2>\n<p>Converts a value to a Python <code>int</code>. Useful when the remote\npatron_information call returns a numeric field as a string (a common\noccurrence) and you need to compare it numerically rather than\nlexicographically.</p>\n<h3>Signature</h3>\n<pre><code class="language-text">int(value) -&gt; int\n</code></pre>\n<h3>Parameters</h3>\n<table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>value</code></td>\n<td><code>Any</code></td>\n<td>Yes</td>\n</tr>\n</tbody></table>\n<ul>\n<li><strong><code>value</code></strong> — The value to convert. Typically a string such as <code>&quot;3&quot;</code> or\na float such as <code>2.9</code>. Any value accepted by Python&#39;s built-in <code>int()</code> is\nvalid. Passing a non-numeric string (e.g. <code>&quot;adult&quot;</code>) raises a <code>ValueError</code>\nand causes the rule to <strong>fail open</strong>.</li>\n</ul>\n<h3>Returns</h3>\n<p><code>int</code> — The integer representation of <code>value</code>. Floating-point values are\n<strong>truncated</strong> toward zero (e.g. <code>int(&quot;2.9&quot;)</code> raises <code>ValueError</code>; pass a\nfloat literal or cast via <code>{field} * 1</code> first if you need truncation of\nfloats).</p>\n<h3>Raises</h3>\n<p><code>ValueError</code> — If <code>value</code> cannot be converted to an integer. At runtime\nthis causes the rule to <strong>fail open</strong>.</p>\n<h3>Examples</h3>\n<pre><code class="language-python"># Block patron class codes above 2 (returned as a string by the remote patron_information call)\nint({sipserver_patron_class}) &gt; 2\n\n# Block if a numeric expiry-year field indicates an expired account\nint({expire_year}) &lt; 2025\n</code></pre>\n<hr>\n<h2>Notes</h2>\n<ul>\n<li><p><strong>String methods are available</strong> — methods on Python <code>str</code> values can be\ncalled directly on string-valued placeholders. For example, to check\nwhether a patron identifier starts with a certain prefix:</p>\n<pre><code class="language-python">{patron_identifier}.startswith(&quot;1234&quot;)\n</code></pre>\n</li>\n<li><p><strong>Fail-open behaviour</strong> — any function call that raises an exception\n(e.g. an unparseable date or a non-numeric string passed to <code>int()</code>)\ncauses the rule to be <strong>skipped</strong> at runtime (the patron is not blocked\nby that rule) and the rule to be <strong>accepted</strong> at admin-save time (with\na warning in the Admin UI that there is a problem with the rule). Write\ntest rules carefully using representative patron data before enabling\nthem in production.</p>\n</li>\n<li><p><strong>No other builtins</strong> — Python builtins such as <code>len</code>, <code>str</code>, <code>float</code>,\n<code>abs</code>, and <code>round</code> are <strong>not</strong> available. If you need additional\nfunctions, request them via the standard feature-request process so they\ncan be reviewed and added to <code>DEFAULT_ALLOWED_FUNCTIONS</code> in\n<code>rule_engine.py</code>.</p>\n</li>\n<li><p><strong>Placeholder syntax</strong> — field values from the remote patron_information\ncall are referenced as <code>{field_name}</code>. All fields returned by the\n<code>patron_information</code> command are available, plus the normalised <code>{fines}</code>\nkey (a <code>float</code> derived from <code>fee_amount</code>).</p>\n</li>\n</ul>\n';
66
export default patronBlockingFunctionsHtml;

0 commit comments

Comments
 (0)