Repository navigation
Support permanent redirects and dotted finding aid ids - #141
Open
gkostin1966 wants to merge 1 commit into
Open
gkostin1966 wants to merge 1 commit into
gkostin1966 wants to merge 1 commit into
Conversation
rename finding_aid_id back to document_id
rshiggin
reviewed
Oct 9, 2026
rshiggin
left a comment
Member
There was a problem hiding this comment.
I leave it up to you whether to make the change to protect from false positives in redirect_resolver.rb.
|
|
||
| def redirect?(id) | ||
| resolve(id) != id | ||
| end |
Member
There was a problem hiding this comment.
claude-opus 5.5 recommends adding "normalize" here to avoid false positives.
def redirect?(id)
- resolve(id) != id
+ resolve(id) != normalize(id)
end
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
merge --squash ARC-192/dots-in-ids-in-urls and reverting finding_aid_id back to document_id
Support permanent redirects and dotted finding aid IDs
Summary
This change adds permanent redirects for finding aids whose EAD IDs have changed and establishes one canonical identifier policy throughout the application.
Finding aid IDs may change for several reasons:
The legacy application replaced dots with hyphens when constructing Solr document IDs.
A stakeholder may assign a new EAD ID to an existing finding aid.
The same finding aid may be renamed more than once over its lifetime.
The application now treats the redirect map as a history of exact old-to-new ID changes and returns an HTTP 301 Moved Permanently response for obsolete IDs. Redirect chains are resolved directly to the newest ID so clients and search engines do not need to traverse multiple redirects.
Canonical identifier policy
Solr document IDs are now the canonical operational identifiers used by routes, downloads, generated artifacts, indexing jobs, and deletion jobs.
Canonical Solr IDs:
Preserve dots.
Strip surrounding whitespace.
Use lowercase characters.
For example:
Source EAD ID: Umich-WCL-F-103.1dub
Solr ID: umich-wcl-f-103.1dub
The original EAD ID remains available in ead_ssi as source metadata, including its original capitalization. Application behavior no longer depends on the raw ead_ssi value.
The custom UmArclight::NormalizedId class is loaded directly by the Traject configuration. This is important because some indexing commands execute Traject as a standalone process and do not load Rails initializers. Loading the normalizer from the Traject configuration ensures that all indexing paths produce the same IDs.
Component reference IDs are also lowercased during indexing so collection and component URLs follow the same canonical-ID policy.
Permanent redirects
config/redirect_map.rb stores lowercase old-to-new ID mappings. It supports both legacy normalization redirects and stakeholder-requested EAD ID changes.
For a rename history such as:
A -> B
B -> C
C -> D
requests for A, B, or C receive a single permanent redirect to D.
The redirect resolver:
Performs case-insensitive lookups.
Preserves dots.
Follows an arbitrary number of rename mappings.
Detects redirect cycles.
Returns the lowercase canonical target.
Redirects historical component URLs by resolving the mapped finding-aid root
while preserving the component suffix.
An exact redirect-map entry takes precedence over component-prefix matching.
When multiple historical finding-aid IDs overlap, the resolver uses the
longest matching root.
Mixed-case requests for current IDs are also redirected to their lowercase canonical URL. This prevents case-sensitive Solr lookups from returning a 404 for an otherwise valid finding aid.
Redirect behavior applies to:
Finding aid and component show pages.
XML downloads.
HTML downloads.
PDF downloads.
Arclight hierarchy endpoints.
Existing query parameters are retained in redirected URLs.
Routing
Catalog routes now accept the complete non-slash path segment as :id. This prevents Rails from interpreting a dot in an ID as a format separator.
Known historical IDs and noncanonical mixed-case IDs are routed to catalog#permanent_id_redirect. Lowercase current IDs continue to use the normal Blacklight catalog#show route.
The redirect is implemented at the HTTP layer rather than through synthetic Solr documents. This provides a real 301 Moved Permanently response without introducing redirect-only records into search results, facets, sitemaps, or other Solr-backed features.
Artifact and deletion behavior
SolrDocument#finding_aid_id returns the root Solr ID:
For a collection, it returns the collection's own Solr ID.
For a component, it returns the component's root collection ID.
XML, HTML, PDF, and temporary package filenames now use this canonical finding aid ID instead of the raw EAD ID.
Finding aid deletion now removes the complete nested Solr document block using root. The supplied ID is normalized and Solr-escaped before the delete query is sent.
Redirect map safeguards
The redirect map is frozen and has automated checks that:
Every key and value is lowercase.
No redirect cycles exist.
The resolver also detects cycles at runtime and raises an explicit error rather than looping indefinitely.
Sample data
Four Bentley sample EAD files with dotted IDs were added:
umich-bhl-87265.0
umich-bhl-87265.4
umich-bhl-87265.11
umich-bhl-87265.25
These provide representative data for verifying indexing, routing, and artifact behavior with dotted finding aid IDs.
Deployment considerations
This changes the canonical Solr ID format for records whose prior IDs contained dots or uppercase characters.
Deployment requires:
Reindexing finding aids so Solr contains the new lowercase IDs with dots preserved.
Regenerating or renaming existing XML, HTML, and PDF artifacts to use canonical Solr IDs.
Removing stale documents indexed under the previous ID format if the reindex process does not clear the index first.
The redirect map preserves access to obsolete public URLs after the new index is deployed.
Test coverage
Coverage includes:
Lowercase, dot-preserving ID normalization.
Standalone Traject indexing behavior.
Preservation of the original EAD ID in ead_ssi.
Lowercase component IDs.
Redirect chains resolving directly to the final target.
Historical component redirects that preserve component suffixes.
Longest-prefix matching for overlapping historical finding-aid IDs.
Case-insensitive redirect lookup.
Mixed-case current-ID canonicalization.
Redirect cycle detection.
Lowercase redirect-map validation.
Dotted-ID route recognition.
Query parameter preservation.
XML download and hierarchy endpoint redirects.
Root finding aid IDs for collections and components.
Normalized and escaped nested-block deletion.