feat(urns): forward URNs retired by publication to the published record - #863
Draft
davereinhart wants to merge 1 commit into
Draft
feat(urns): forward URNs retired by publication to the published record#863davereinhart wants to merge 1 commit into
davereinhart wants to merge 1 commit into
Conversation
publish_score_set overwrites the tmp:<uuid> URN of an experiment set, an experiment and a score set in place, and refresh_variant_urns rebuilds every variant URN from the score set's. Nothing recorded the old value, so a link already shared to the unpublished record began returning 404 under a name the caller had no way to guess. Reloading a score set page after publishing it was enough to hit this. Record what each URN became in a new urn_redirects table, and resolve it in forward_retired_urns, an application-wide dependency: a read naming a retired URN is answered 308 to the same path under the record's current URN. One implementation covers every route that takes a URN, sub-resources included, and since substitution operates on the URN substring, a variant follows its score set without a row of its own. A dependency rather than ASGI middleware, because it needs the request's session; middleware runs outside dependency resolution, so it would open a session of its own that no dependency_overrides could redirect. Reads only: an owner is permitted to publish a published score set, so forwarding a stale POST .../publish would rename a live public record. And only onto a target confirmed public, since a Location header names its target to an anonymous caller before any route checks a permission. That check also keeps a deleted record's surviving row from answering a permanent redirect with a 404. The dependency reads the path from the ASGI scope. request.url.path truncates at the '#' in a variant URN, because Starlette rebuilds that URL by re-parsing it, which turns everything after the '#' into a fragment and drops the variant number, the sub-resource and the query string. lib/logging/context.py has the same pattern and is left for a separate change. Forwarding is one hop, which is all that can arise while nothing renames a published record. URNs retired before this are unrecoverable, since publication overwrote them and kept no history, so the table is not backfilled and links to records published earlier stay broken.
davereinhart
marked this pull request as draft
September 2, 2026 21:48
Coverage Report for CI Build 33687149340Warning No base build found for commit Coverage: 88.958%Details
Uncovered Changes
Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats
💛 - Coveralls |
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.
This pull request introduces a robust mechanism for forwarding requests that use "retired" URNs (Uniform Resource Names) to the current, published URNs for datasets, experiments, and score sets. This ensures that links shared before publication continue to work after a record is published and its URN changes. The implementation covers database schema changes, backend logic, API integration, and tests.
URN Redirects: Database and Model Support
urn_redirectstable (with migration) and corresponding SQLAlchemy modelUrnRedirectto track mappings from old (retired) URNs to new (published) URNs. This enables the system to look up and forward requests for outdated URNs. [1] [2]urn_redirectmodel in the models package for application-wide access.URN Redirect Logic and Integration
record_urn_redirectand related logic inurn_redirects.pyto record URN changes and determine when a request should be forwarded. Only public, published records are eligible as redirect targets, and only read requests (GET/HEAD) are forwarded.API and Application Integration
forward_retired_urnsdependency globally to all FastAPI routes, ensuring that any request using a retired URN is automatically redirected to the current URN if appropriate. [1] [2] [3]Testing
Refs: VariantEffect/mavedb-ui#617