Commit Graph

1821 Commits

Author SHA1 Message Date
Pavel Balashou 5af7d211c8 [#74977] Modify friendly_id_slugs constraints.
https://community.openproject.org/wp/74977

Add NOT NULL to *sluggable_type* and fix NULL *scope* uniqueness in *friendly_id_slugs*

- Delete duplicate NULL *scope* rows, keeping the most recent per (slug, sluggable_type)
- Delete NULL *sluggable_type* rows before adding NOT NULL constraint
- Replace unique index on (slug, sluggable_type, scope) with NULLS NOT DISTINCT variant (requires Postgres 15+)

Why?

1. *sluggable_type* NOT NULL
  every slug must belong to a model (e.g. Post, User). A slug with no *sluggable_type* is orphaned and meaningless.
2. NULLS NOT DISTINCT in the unique constraint
  not treating every NULL *scope* as unique leads to duplicate records if *scope* is NULL which does not make sense
  and pollutes the table with unnecessary data
2026-05-19 11:14:41 +02:00
Jan Sandbrink 6a6982b9a1 Merge pull request #23007 from opf/core-health-reports
Move storage of HealthReports into dedicated model
2026-05-07 08:13:06 +02:00
Klaus Zanders a94193b96d Merge pull request #23057 from opf/dependabot/bundler/dev/good_job-4.18.2
Bump good_job from 4.18.1 to 4.18.2
2026-05-06 10:26:57 +02:00
Jan Sandbrink 048b03e28b Move storage of HealthReports into dedicated model
So far they have only been stored in the Rails cache, making
them pretty volatile. They are now properly stored in the database,
theoretically allowing to also retrieve older health check results and
compare them to newer ones.

Translation responsibilities have been moved into respective components,
that are rendering the results.

This is part of a refactoring that moves health reports and their components
out of the storages module into the core, allowing them to be reused by different
modules.
2026-05-06 08:22:30 +02:00
Dombi Attila 72f584942d Redo "Split the root Agent.md files into subdirectories."
This reverts commit 7d49707c4b.
2026-05-05 22:39:59 +03:00
Klaus Zanders 8359ca418b Run bin/rails g good_job:update for current migrations 2026-05-05 16:38:58 +02:00
Klaus Zanders b1a10567cf Add the category to persisted view 2026-04-24 12:03:59 +02:00
Klaus Zanders 2da690745e Allow queries to not have a name to properly work with in-memory 2026-04-23 10:38:11 +02:00
Klaus Zanders d23ba80489 Fix default value for options hash in views 2026-04-23 10:38:06 +02:00
Klaus Zanders 67b714ef14 Fix default value and nullability of fields 2026-04-23 10:38:03 +02:00
Klaus Zanders 8ad36144c3 Allow adding single entities to the query 2026-04-23 10:38:03 +02:00
Klaus Zanders 349caed48c Introduce models for persisted views and queries 2026-04-23 10:38:02 +02:00
Klaus Zanders 581776e359 Add index for OU flag 2026-04-14 09:58:07 +02:00
Tomas Hykel c4debc8aaa [#73523] Implement WorkPackage semantic ID allocation system 2026-04-01 17:25:19 +02:00
OpenProject Actions CI 72cd07e1ff Merge branch 'release/17.3' into dev 2026-03-31 13:57:55 +00:00
Dombi Attila 872c689474 [#73556] Add Start/Stop sprint permission to users with Create sprint
https://community.openproject.org/work_packages/73556
2026-03-31 13:18:20 +03:00
Kabiru Mwenja 2c95192f44 Use SettingRenamer.rename_value in identifier setting migration
Simplify the migration by delegating to the new SettingRenamer utility
instead of inlining the SQL.
2026-03-28 10:06:30 +03:00
Kabiru Mwenja d240267b25 Add rename_value to SettingRenamer migration utility
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.
2026-03-28 10:05:37 +03:00
Kabiru Mwenja d3734a7485 Rename work_packages_identifier setting values to "classic" and "semantic"
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.
2026-03-28 10:01:57 +03:00
Kabiru Mwenja 2b4478da68 Merge pull request #22406 from opf/open-point/73149-how-do-we-handle-project-identifiers-case-insensitive-storage
Add case-insensitive uniqueness enforcement for project identifier
2026-03-27 13:26:38 +03:00
Jan Sandbrink f9d8bc6614 Introduce SubclassResponsibility error
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
2026-03-27 08:14:56 +01:00
Kabiru Mwenja f0ff8030ec Cleanup tests and add lossy rollback note
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.
2026-03-24 08:10:18 +03:00
Kabiru Mwenja db932c049f Harden deduplication against secondary collisions
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.
2026-03-24 08:04:08 +03:00
Kabiru Mwenja 674b5cd96c Deduplicate case-colliding identifiers before adding unique index
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).
2026-03-23 19:14:47 +03:00
Kabiru Mwenja e369227c39 Add case-insensitive project identifier storage
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.
2026-03-20 20:27:04 +03:00
Judith Roth d688db21e3 Merge pull request #22397 from opf/implementation/72917-save-the-previous-value-when-a-project-identifier-changes
[#72917] Save the previous value when a project identifier changes
2026-03-19 09:56:01 +01:00
Judith Roth 359cd1c2ae [#72917] Squash migrations for readability 2026-03-18 16:59:42 +01:00
Klaus Zanders 3e873e1649 Merge branch 'dev' into user-working-times 2026-03-18 15:58:55 +01:00
Judith Roth df4cb24217 [#72917] Save the previous value when a project identifier changes
https://community.openproject.org/work_packages/72917

This leverages friendly_id's history module:
https://github.com/norman/friendly_id/tree/master
https://norman.github.io/friendly_id/file.Guide.html#History__Avoiding_404_s_When_Slugs_Change

We decided on keeping friendly_id because it was already used and offers
exactly the functionality we need.

Implementing redirects from routes that use an old identifier to the
current one will be a separate commit (see
https://community.openproject.org/wp/72918)
2026-03-18 14:25:59 +01:00
Dombi Attila 7d49707c4b Revert "Split the root Agent.md files into subdirectories." 2026-03-18 14:56:43 +02:00
Klaus Zanders 7a3a78ceae Merge branch 'dev' into user-working-times 2026-03-18 11:16:01 +01:00
Dombi Attila 1902ec436c Split the root Agent.md files into subdirectories. 2026-03-18 11:25:42 +02:00
Klaus Zanders 31a2536f51 Implement has_principal_details concern and use it for the group 2026-03-16 15:42:27 +01:00
Andrej 15baa3520d Merge branch 'dev' into merge-release/17.2-20260316105331 2026-03-16 11:54:11 +01:00
Oliver Günther c3b075d391 Merge remote-tracking branch 'origin/release/17.1' into release/17.2 2026-03-16 11:11:43 +01:00
Oliver Günther 30ef57877c Merge remote-tracking branch 'origin/release/17.0' into release/17.1 2026-03-16 11:10:12 +01:00
Oliver Günther 8d61c5fe7f Merge remote-tracking branch 'origin/release/16.6' into release/17.0 2026-03-16 11:08:23 +01:00
Klaus Zanders 41f3e47475 Run migration to remove ascii control characters from Custom Field Names 2026-03-13 10:18:28 +01:00
Andrej 0f3e6bd56e Merge branch 'dev' into merge-release/17.2-20260311143330 2026-03-11 15:35:31 +01:00
Klaus Zanders 59696bbd7d Merge branch 'dev' into user-working-times 2026-03-11 14:25:33 +01:00
Markus Kahl 05ac3219e3 handle case where show_work_package_attachments is not defined 2026-03-11 06:48:29 +00:00
Alexander Brandon Coles bb1eb75e20 Merge branch 'dev' into merge-release/17.2-20260310041552
# Conflicts:
#	config/locales/crowdin/uk.yml
#	modules/backlogs/config/locales/crowdin/uk.yml
#	modules/budgets/config/locales/crowdin/ko.yml
#	modules/meeting/config/locales/crowdin/de.yml
2026-03-10 05:37:12 -03:00
Pavel Balashou 58cfb67c54 Fix Rubocop and add some jira related specs. 2026-03-09 16:10:52 +01:00
Pavel Balashou 10299f9943 Fix some jira import bugs. Add finalization modal.
- 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.
2026-03-09 16:10:17 +01:00
Jens Ulferts 6085432e9f Merge pull request #22195 from opf/bug/72801-sharing-permission-dependencies-are-not-migrated
[#72801] Sharing permission dependencies are not migrated
2026-03-09 09:21:34 +01:00
Dombi Attila 116ed1ccf8 Restore the select_done_statuses permission. 2026-03-06 17:07:13 +02:00
Klaus Zanders 0db321fe73 Fix setup for constraint 2026-03-06 13:28:40 +01:00
Klaus Zanders 727cb945e8 Refactor UserNonWorkingDay into a model that covers date ranges 2026-03-06 13:28:35 +01:00
Klaus Zanders 83a92ba250 Fix display of history to include current, unique constraint 2026-03-06 13:28:22 +01:00
Klaus Zanders 8cb25833de Add working hours and non working days for users 2026-03-06 13:27:42 +01:00