Skip to content

Normalize compliance lookups on write and consolidate the duplicated loop - #1199

Merged
labkey-martyp merged 3 commits into
release26.3-SNAPSHOTfrom
26.3_fb_shared_lookup_normalization
Sep 10, 2026
Merged

Normalize compliance lookups on write and consolidate the duplicated loop#1199
labkey-martyp merged 3 commits into
release26.3-SNAPSHOTfrom
26.3_fb_shared_lookup_normalization

Conversation

@labkey-martyp

@labkey-martyp labkey-martyp commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Rationale

employeeperunit and sopdates were the only tables in ehr_compliancedb without trigger scripts, so their lookup values were never canonicalized on write, and this branch both adds those scripts and replaces the normalization loop that every other script in the schema had copied verbatim. The missing canonicalization is why the ONPRC report procedures had to wrap every unit and category comparison in lower(); that lower() removal has already merged, so those reports are exposed to case drift until this deploys.

Existing rows carrying off-lookup values need a backfill before this deploys. The scripts merge the old row into the new one before validating, so a stored value that no longer matches its lookup will block edits that work today.

Related Pull Requests

Changes

  • Adds trigger scripts for employeeperunit and sopdates, normalizing the lookup columns their schema metadata already declares.
  • Leaves sopdates.sopid out deliberately: its fk to sops is commented out, and a lookup against a column with no fk would reject every row.
  • Converts the six existing ehr_compliancedb scripts to the shared helper, with field lists and error text unchanged so behavior is identical.

Tasks

  • Claude Code Review
  • Code Review

Replaces the copied normalization loop in six ehr_compliancedb trigger scripts. Field lists and error text are unchanged, so behavior is identical; the matching LDK change must be deployed first or the require() fails to compile.
employeeperunit was the only table in ehr_compliancedb with no trigger script, so its employeeid, unit, and category values were never canonicalized against their lookups - the reason the ONPRC report procedures had to wrap every unit and category comparison in lower(). Its schema metadata already declares all three columns as lookups.

sopdates had no trigger script either. sopid is deliberately left out of its lookup fields: the fk to sops is commented out in ehr_compliancedb.xml, and getLookupValue returns null for a column with no fk, which would reject every row.

The lower() removal these pair with has already merged (onprcEHRModules PR 1859), so those reports are exposed to case drift until this deploys. Existing rows carrying off-lookup values need a backfill first, since beforeUpdate revalidates the merged old row and will otherwise block edits that work today.
Adds the matching delete guards, so renaming or deleting an employee, unit, or category can no longer strand employeeperunit rows that its new trigger would then reject.
addError(errors, fieldName, 'Cannot delete row with value: ' + row[fieldName] + ' because it is referenced by the sopbycategory table');
}

if (helper.verifyNotUsed('ehr_compliancedb', 'employeeperunit', 'category', row[fieldName], 'employeecategory')){

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verifyNotUsed() method name is so confusing given that it actually returns true when value is used!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to respond. It is weird naming but would require a larger set of PRs to refactor which is out of scope for this PR.

labkey-martyp added a commit to LabKey/LabDevKitModules that referenced this pull request Sep 10, 2026
## Rationale

Eleven trigger scripts across the EHR compliance and ONPRC modules had
each copied the same loop for case-normalizing lookup values on write,
so this adds the single shared implementation they can call instead. The
helper takes the LookupValidationHelper as an argument rather than
constructing one, because that class caches each lookup target's
allowable values per instance: callers keep creating it at script scope,
where the target table is read once per batch instead of once per row.

## Related Pull Requests

- LabKey/ehrModules#1199 — converts the EHR
compliance scripts to this helper.
- LabKey/onprcEHRModules#1885 — converts the
ONPRC scripts.

This must merge and deploy first. A consumer script that requires the
new function against an un-updated LDK fails at script compile time.

## Changes

- Adds `LDK.Server.Utils.normalizeLookupFields`, which replaces each
named field's value with the canonically-cased value from its lookup
target and reports a field error for any value the target does not
contain.
- Documents why the validation helper is a parameter, since creating one
per call would silently turn a per-batch read of each lookup target into
a per-row read.

## Tasks

- [x] Claude Code Review
- [x] Code Review
labkey-martyp added a commit to LabKey/onprcEHRModules that referenced this pull request Sep 10, 2026
## Rationale

Three ONPRC trigger scripts carried their own copy of the lookup
normalization loop, and this converts them to the shared LDK helper. It
is a pure refactor: the field lists and error text are unchanged, so no
column starts being validated that wasn't already and no additional
lookup target gets read.

## Related Pull Requests

- LabKey/LabDevKitModules#310 — adds the shared
helper this depends on, and must merge first.
- LabKey/ehrModules#1199 — the same conversion
in the EHR compliance module.

## Changes

- Converts the compliance and scheduling trigger scripts in this repo to
the shared helper, leaving their behavior identical.

@labkey-martyp labkey-martyp left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No new EHR failures due to this PR.

@labkey-martyp
labkey-martyp merged commit 9add4bd into release26.3-SNAPSHOT Sep 10, 2026
7 of 9 checks passed
@labkey-martyp
labkey-martyp deleted the 26.3_fb_shared_lookup_normalization branch September 10, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants