Repository navigation
Conversation
cb0c78e to
649dd44
Compare
| `Name` varchar(100) NOT NULL, | ||
| `Format` varchar(255) NOT NULL, | ||
| `IsRequired` boolean NOT NULL DEFAULT 1, | ||
| `IsUnique` boolean NOT NULL DEFAULT 1, |
There was a problem hiding this comment.
Commenting here because it's hard to comment on the PR description..
I don't see why "IsUnique" is required. What is a "non-unique" identifier example? An identifier that isn't unique can't be used to identify the candidate, which is the point of an identifier.
There was a problem hiding this comment.
I have sad news for you Dave... 1 word: scanner hahah
The truth is other than PSCID not being unique, we have several other identifiers that could be shared, potentially something like "Family ID" but on CBIG we also want to allow projects to add their own internal identifiers where in some cases they are not unique...
The main driver for this however was PSCID= scanner
There was a problem hiding this comment.
oh and GUID doesnt have to be unique either, and before you spell out GUID for me... GUID should be unique to the participant but the participant can have multiple entries on the same platform by design (coming from separate databases or sources)
There was a problem hiding this comment.
Maybe this would be a good opportunity to just get rid of the "PSCID=scanner" hack and just.. don't assign scanners a PSCID.
As for GUIDs, if I understand correctly that's what the AllowMultiple flag is for in this description (not the IsUnique one).
There was a problem hiding this comment.
Maybe this would be a good opportunity to just get rid of the "PSCID=scanner" hack and just.. don't assign scanners a PSCID.
Love the idea but not in the context of this PR, its a whole mountain of work on its own.
As for GUIDs, if I understand correctly that's what the AllowMultiple flag is for in this description (not the IsUnique one).
AllowMultiple: A Participant can have more than one RedCapID (just an example)
isUnique: 4 Different participants can have the same GUID because in reality they are the same participant recruited separately for 4 different studies and neither of those studies knows of this participant's involvement in the others
What is the reasoning for this? I get that one permission makes it easier to implement which makes sense, but if that's a permanent design decision then why have a separate rel table instead of just a column in the identifier type table to list the one permission? As for a permission only being allowed to be associated with one identifier type.. why? Multiple different related identifier types having the same permission seems reasonable and I can't think of any way that adding this restriction would simplify the implementation. |
Yes, thank you for bringing it up. What I meant is that an identifier type can have at most one permission, but the same permission can be used by multiple identifier types. With that relationship, I think your point about the separate relation table makes sense too. Since it’s many to one, permID could just be a nullable foreign key on the identifier type table. The relation table would only really be needed if we wanted multiple permissions per identifier type later. |
a617af0 to
93e2302
Compare
`CandID` is the candidate identifier the application keys on, but the `candidate` table doesn't carry an index for it. It indexes `PSCID`, `ExternalID`, `Active`, `RegistrationCenterID`, `flagged_reason`, `Sex` and `ProbandSex`, but not `CandID`. So every lookup by CandID is a full table scan. That stays invisible until something does a lot of them at once. The dataquery run endpoint resolves CandID to `candidate.ID` once per result row, batched 2000 rows at a time, so each batch does 2000 scans. On a 32,487 candidate instance that is 65 million row reads per batch. Measured there, a batch went from 74.89 s to 0.32 s. The index is unique, which is what `CandIDGenerator` already assumes. It picks a random ID, checks the table for a collision, and returns it for insertion. The check and the insert are separate statements, so what stopped two concurrent registrations landing on the same CandID was the primary key the table used to carry on that column. Since aces#9556 moved the primary key to `candidate.ID`, nothing has.
Bumps [smarty/smarty](https://github.com/smarty-php/smarty) from 4.5.6 to 4.5.7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/smarty-php/smarty/releases">smarty/smarty's releases</a>.</em></p> <blockquote> <h2>v4.5.7</h2> <h2>What's Changed</h2> <ul> <li>Port security fixes from v5.8.2 to Smarty v4. by <a href="https://github.com/wisskid"><code>@wisskid</code></a> in <a href="https://redirect.github.com/smarty-php/smarty/pull/1194">smarty-php/smarty#1194</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/smarty-php/smarty/compare/v4.5.6...v4.5.7">https://github.com/smarty-php/smarty/compare/v4.5.6...v4.5.7</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/smarty-php/smarty/blob/v4.5.7/CHANGELOG.md">smarty/smarty's changelog</a>.</em></p> <blockquote> <h2>[4.5.7] - 2026-06-29</h2> <ul> <li>Security: prevent symlinks inside a trusted <code>secure_dir</code>/template directory from being used to read files outside of it (CWE-22 path traversal), affecting <code>{include}</code> and <code>{fetch}</code> of local files</li> <li>Security: <code>{html_image}</code> now escapes the <code>file</code>, <code>path_prefix</code>, <code>href</code>/<code>link</code>, <code>width</code> and <code>height</code> attributes (it already escaped <code>alt</code> and pass-through attributes), and <code>{html_select_date}</code> casts <code>day_size</code>/<code>month_size</code>/<code>year_size</code> to int (matching <code>{html_select_time}</code>), preventing untrusted values passed into these attributes from breaking out of the generated HTML (CWE-79)</li> <li>Security: <code>{fetch}</code> no longer follows HTTP redirects for remote resources while a security policy is active, preventing an open redirect on a trusted host from bypassing <code>trusted_uri</code> (CWE-918 server-side request forgery)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/smarty-php/smarty/commit/838d6ad1c635f8a6bafc08d791b8af18d8304b3a"><code>838d6ad</code></a> Merge branch 'release/4.5.7' into support/4</li> <li><a href="https://github.com/smarty-php/smarty/commit/187f7b6246de8195398241332ce8fa69c719ff4e"><code>187f7b6</code></a> version bump</li> <li><a href="https://github.com/smarty-php/smarty/commit/a1ccdb0518021a559b4066c37b76a42c86bbce90"><code>a1ccdb0</code></a> Port security fixes from v5.8.2 to Smarty v4. (<a href="https://redirect.github.com/smarty-php/smarty/issues/1194">#1194</a>)</li> <li><a href="https://github.com/smarty-php/smarty/commit/c285f84fc66212c0e1c73780bbebe07771e6e5bf"><code>c285f84</code></a> Reproduce block override leakage in template inheritance</li> <li>See full diff in <a href="https://github.com/smarty-php/smarty/compare/v4.5.6...v4.5.7">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ierGeneratorTest meant to replace it later on
…ReworkCandidateIdentifiers
Brief summary of changes
The goal is to support multiple identifier types with different formats, validation rules, permissions, and project-specific requirements.
The rework separates identifier configuration from the values assigned to candidates, providing a more flexible architecture that can be integrated across LORIS modules while maintaining backward compatibility.
This PR depends on #11209 and focuses on the domain models, persistence, identifier generation, and validation, while the database structure and configuration migration are handled in the preceding PR.
Changes
Domain models and persistence
Added
IdentifierTypeandCandidateIdentifierdomain models.Added
IdentifierTypeControllerto manage identifier type configurations and project associations.Added
CandidateIdentifierControllerto handle identifier creation, retrieval, updates, deletion, and validation.Implemented application-level enforcement of uniqueness and multiple-value rules.
Identifier generation
Added
CandidateIdentifierGeneratoras a generalized generator supporting sequential and random identifier generation through configurable templates.It currently duplicates some functionality from
SiteIDGenerator, which is used byPSCIDGeneratorandExternalIDGenerator.The goal is to eventually replace
PSCIDGeneratorandExternalIDGeneratorwith the new configurable generator, removing the need for separate generation implementations.The existing generators remain in place until the new identifier framework is integrated into candidate workflows.
The REST API endpoints for managing candidate identifiers are implemented separately in PR #11253.
Tests
Added unit tests for
IdentifierTypeController.Added unit tests for
CandidateIdentifierController.Added unit tests for
CandidateIdentifierGenerator.Updated existing identifier-related tests to support the template-string changes.
Remaining work
The next stages of the rework will focus on:
Project configuration: Build on the existing project associations to enforce project-specific identifier requirements and validation.
Architecture review: Validate the design and implementation against the requirements, conduct integration testing, and incorporate feedback.
Application integration: Integrate identifiers into candidate registration and management workflows, including search, lookup, identifier creation UI, and permission-based visibility.
Administration and migration: Implement the administration UI for managing identifier types, complete migration validation and regression testing, and ensure backward compatibility.
Documentation and release readiness: Complete developer and configuration documentation, address remaining issues, and prepare the framework for inclusion in LORIS core.