Complement the existing rename (for setting names) with rename_value
for updating stored setting values. This provides a reusable helper
for future migrations that need to rename allowed values.
The setting previously used "numeric" and "alphanumeric" as its allowed
values. Rename them to "classic" and "semantic" to better align with the
product terminology for the work package identifier modes.
Includes a migration to update any stored setting values in the database,
updated constants and helper methods on Setting::WorkPackageIdentifier,
and all corresponding references across models, components, forms,
frontend controllers, locales, and specs.
This error is intended for cases when a method is
intentionally not implemented, because the module/class defining
it expects a subclass (or class including the module) to implement
the method.
This is intended to distinguish it from other cases, such as:
* feature not implemented yet
* edge case of a method call not yet supported
Notably it avoids the misuse of the Ruby-defined NotImplementedError,
which is only intended for much more specific scenarios:
> Raised when a feature is not implemented on the current platform. For example, methods depending on the fsync or fork system calls may raise this exception [...]
Also see https://docs.ruby-lang.org/en/master/NotImplementedError.html
Unify test helpers into a single create_project_with_raw_identifier
method that better communicates intent (bypasses validations to set
an exact identifier). Add project.reload after update_all so the
in-memory object stays consistent with the database.
Also documents that the migration rollback is intentionally lossy —
deduplicated identifiers keep their suffixes under the restored
case-sensitive index.
Switch suffix from dash to underscore so deduplicated identifiers
remain valid in both numeric and alphanumeric modes. Add a NOT EXISTS
guard to skip rows where the suffixed identifier would itself collide
with an existing LOWER(identifier). In the astronomically unlikely
event of a secondary collision, the subsequent CREATE UNIQUE INDEX
will fail loudly rather than silently produce bad data.
PostgreSQL enforces uniqueness constraints at index build time — when
CREATE INDEX encounters duplicate key values, the entire operation
fails. For concurrent index builds (algorithm: :concurrently), this is
particularly problematic: a failed build leaves behind an "invalid"
index entry in pg_class that is ignored for queries but still incurs
write overhead on every INSERT/UPDATE, and must be explicitly dropped
before retrying.
Since this migration introduces a unique index on LOWER(identifier),
any pre-existing case collisions (e.g. "MyProject" and "myproject")
would cause the index build to fail. This adds a deduplication step
that resolves collisions before the index is created: the oldest
project (lowest id) keeps its identifier unchanged while newer
duplicates receive a "-N" suffix via a window function partitioned
over LOWER(identifier).
Introduce case-insensitive handling for project identifiers:
- Add `normalizes :identifier` to automatically upcase (alphanumeric
mode) or downcase (numeric mode) identifiers on assignment
- Add `parse_friendly_id` to normalize FriendlyId lookups for
case-insensitive finder queries
- Switch uniqueness validation to `case_sensitive: false`
- Replace inline `exclusion:` validator with explicit
`identifier_not_reserved` that checks case-insensitively
- Consolidate alphanumeric format validators into a single
`identifier_alphanumeric_format` method with early return to
prevent cascading error messages
- Use case-insensitive LOWER() comparison in historical identifier
reservation check
- Add `post_process` support to the OpActiveRecord acts_as_url
adapter with an allowlist of safe transforms (upcase/downcase)
- Add migration to replace the unique index on projects.identifier
with a case-insensitive LOWER(identifier) index
- Update table definition to match the new index
Includes corresponding test additions for normalization, case-
insensitive uniqueness, reserved identifier rejection, and the
create_spec fixture fix for alphanumeric mode.
- Modify jira_open_project_references unique constrant
It must include jira_id, because multiple jira configuration can refer same op entities.
- Add finalization modal
- Add finalization job
The job activates all imported users. Checks that user_limit has not been exceeded with specific contact.
Destroys jira_* objects.
- Destroy jira object on revert as well.
- Use EmptyContract when creating Attachements, WorkPackages, Members
- Import only users fetched in the current jira_import. It was a bug.
https://community.openproject.org/work_packages/72801
- Complete missing dependencies for view_sprints, create_sprints,
manage_sprint_items
- When migrating backlog permissions down, do not restore permissions
where the source permission cannot be determined.
- When migrating up, do not add manage_sprint_items to roles with add or
edit work package permission
- Remove unnecessary dependencies of the manage_sprint_items
The global setting and the project-level setting are inverted w.r.t. each other,
thus the migration needs to negate the boolean from the global setting.
This is now ensured with a migration spec as well.
https://community.openproject.org/wp/72671
The default custom field section was created with an empty
`display_representation` (`{}`), causing project attributes to not appear
on the project overview page even when enabled by users.
New sections correctly receive the default overview visibility area
(`"sidebar"`), but the default section was not initialized with it.
Add a migration to backfill existing default sections that have an
empty `display_representation` with the default value
`{ overview: "sidebar" }`.