v1.3.0 — no duplicates across records (`@UVUNIQUE`)
Fourth validation mode, and the module's first server round-trip: field-level
uniqueness, which REDCap has no native equivalent for. As the value is typed,
the browser asks the server whether it is already recorded in another record
(framework AJAX — CSRF-protected, survey-aware) and shows used/free live with
the usual message/confirm/block enforcement.
@UVUNIQUEtag /uniquemode. Bare (project-wide),=project|dag|event
scope shorthand, or JSON{with, scope, when, message, blockSave, surveys}.
withmakes the key composite (value + those fields together unique, e.g.
specimen ID within site); available in all three configuration channels
(new dialog boxes: composite fields, scope, survey opt-in).- Privacy posture. The endpoint re-derives scope/composite from stored
rules — nothing security-relevant is trusted from the page — and answers
ONLY for fields carrying a live unique rule, so it cannot be used as an
existence oracle for arbitrary fields. Staff see the colliding record id
only inside their own DAG; surveys are an explicit per-rule opt-in
(surveys:true) answered boolean-only, never a record id. - Fail-open transport. No JSMO, a network error, an error response, or an
answer that never arrives — each leaves the field unflagged and never traps
a save; the console explains why. A one-deep answer cache plus a pending-key
guard means one request per candidate value (the direct listeners and the
when-registry self-watch cannot double-fire a request), and stale responses
are discarded by sequence. - The race is audited, not denied. Two near-simultaneous saves can both
pass the live check; the post-save audit re-checks the saved value against
every other record (same scope/composite semantics via one shared
findCollision) and logstype: unique, reason: duplicate-value. - Field types. Text, Notes, dropdown, radio, yes/no, true/false, slider
(no calc); composes with the other modes on one field. - Verification. New
tests/unique_dom_js.cjs(32 checks: transport stub,
payload shape, composite re-check, fail-open paths, pending/stale/cache,
survey opt-in, when-gate, composition);tests/hook_php.php151→175 (the
AJAX endpoint end-to-end: collision/self-exclusion/trim, anti-oracle,
composite, survey opt-in + boolean-only, DAG masking both directions,
payload hygiene, event-scope read, audit backstop, JSMO injection on/off,
dialog save-gate);tests/annotation_php.php121→136. Full JS + PHP
7.4/8.3 suites green.
Universal Field Validator is a REDCap external module. Rule kinds: @UVALIDATE (check-character / regex), @UVASSERT (cross-field constraints), @UVREQUIRED (conditional required), @UVUNIQUE (no duplicates across records), @UVCHOICES (dynamic choice filtering).
Docs: README · User guide · Action-tag examples · Install