Content
View differences
Updated by Kabiru Mwenja about 1 month ago
**As** a user of an OpenProject instance configured which is set to use project-based work package identifiers
**I want to** use URLs containing with those identifiers
**so that** I can share them with teammates or paste them into copy those to other tools, tools and anyone seeing the people can from that URL can tell see which project the work package belongs to. to
## Acceptance criteria
* URLs like `/work_packages/PROJ-42` open resolve to the correct work package in:
* Full view
* Split view
* (full view, split view, and BIM views
views)
* The same API v3 endpoint `GET /api/v3/work_packages/PROJ-42` resolves the work package can be opened by its numeric ID semantic identifier
* Scoped queries (e.g. `/work_packages/12345`) - nothing breaks for instances that don't use `WorkPackage.visible(user).find("PROJ-42")`) resolve semantic identifiers transparently
* If a `WorkPackage.exists?("PROJ-42")` returns `true` when the semantic identifier exists
* Historical/aliased identifiers (from project is renamed, older identifiers (e.g. `OLDNAME-42`) renames) still resolve via the `work_package_semantic_aliases` table
* Numeric IDs continue to the same work package in all URL positions — no regressions for classic mode
* Opening When a URL with an semantic identifier that doesn't exist shows is not found, the response is a standard "work package not found" page 404 with a work-package-specific error message (not a generic 404)
* Users only see The API v3 work packages they have permission to view - typing a guessed identifier into the URL does not bypass permissions package form endpoint correctly handles semantic identifiers in parent references
* Links Adapt generated inside the product (e.g. copy-to-clipboard, breadcrumbs, parent links) routes such as clipboard copy to use the semantic identifier when the feature Ids
## Technical notes
* `WorkPackage::SemanticIdentifier::FinderMethods` module is enabled included in `WorkPackage` and extended onto every AR relation, overriding `find` and `exists?` to dispatch via `semantic_id?`
* The public `semantic_id?` predicate: strips whitespace, rejects non-strings and numeric strings, returns true only for `PROJECTID-SEQ` patterns — replaces FriendlyId's `Object#friendly_id?` monkey-patch
* Resolution chain: check `identifier` column first, then fall back to `work_package_semantic_aliases` table for historical identifiers
* `ID_ROUTE_CONSTRAINT` constant centralised in `WorkPackage::SemanticIdentifier` — single source of truth for both `config/routes.rb` and frontend `WP_ID_URL_PATTERN`
* Rails route constraint widened from `/\d+/` to accept both numeric and `PROJECTID-SEQ` patterns
* API accepts v3 route parameter changed from `type: Integer` to `type: String` to accept semantic identifiers wherever it accepts numeric work package IDs, including when referencing a parent work package IDs
* Controller and ViewComponent finders updated to use `find_by_id_or_identifier` instead of `find`
* `RecordNotFound` raised with structured `model:`, `primary_key:`, and `id:` fields for error reporting
## Permissions and visibility considerations
* **Who sees this:** **Visible to:** all users with who have permission to view work packages. Using a semantic packages — the identifier format in a the URL does not change who can access what. authorization checks
* **When it applies:** only on instances where **Not visible when:** the semantic work package identifiers feature flag is enabled. On other instances, URLs continue disabled at the instance level (routes still accept the pattern but no semantic identifiers will have been assigned)
* Authorization is unchanged: `WorkPackage.visible(user)` scoping applies before identifier resolution, so users cannot access work packages they lack permission to use numeric IDs as before. view by guessing semantic identifiers
## Translations Translation considerations
* No new user-facing strings. Existing "work package not strings — this is a routing/resolution layer change
* Error messages for "not found" messages are reused. reuse existing `WorkPackage` record-not-found translations
## Out of scope
* Displaying Generating or displaying semantic identifiers in the UI (covered by <mention class="mention" data-id="73716" data-type="work_package" data-text="#73716">#73716</mention> PRs #22704 and <mention class="mention" data-id="73717" data-type="work_package" data-text="#73717">#73717</mention> ) #22710)
* Assigning Allocating semantic identifiers to work packages (covered by the sequence allocation feature)
* Admin settings for enabling or configuring the enabling/configuring semantic identifier format
* Redirecting numeric URLs to semantic URLs - both (both forms remain valid valid)
* Sharing/copy-to-clipboard UI for semantic URLs
**I want to** use URLs containing
**so that** I can share them with teammates or paste them into
## Acceptance criteria
* URLs like `/work_packages/PROJ-42` open
* Full view
* Split view
*
* Scoped queries
* If a
* Historical/aliased identifiers (from
* Numeric IDs continue
* Opening
* Users only see
* Links
## Technical notes
* `WorkPackage::SemanticIdentifier::FinderMethods` module
* The public
* Resolution chain: check `identifier` column first, then fall back to `work_package_semantic_aliases` table for historical identifiers
* `ID_ROUTE_CONSTRAINT` constant centralised in `WorkPackage::SemanticIdentifier` — single source of truth for both `config/routes.rb` and frontend `WP_ID_URL_PATTERN`
* Rails route constraint widened from `/\d+/` to accept both numeric and `PROJECTID-SEQ` patterns
*
* Controller and ViewComponent finders updated to use `find_by_id_or_identifier` instead of `find`
* `RecordNotFound` raised with structured `model:`, `primary_key:`, and `id:` fields for error reporting
## Permissions and visibility
* **Who sees this:**
* **When it applies:** only on instances where
* Authorization is unchanged: `WorkPackage.visible(user)` scoping applies before identifier resolution, so users cannot access work packages they lack permission
## Translations
* No new user-facing strings. Existing "work package not
* Error messages for "not
## Out of scope
* Displaying
* Assigning
* Admin settings for enabling or configuring the
* Redirecting numeric URLs to semantic URLs - both
* Sharing/copy-to-clipboard UI for semantic URLs