Skip to content

poc: Full Observed Versions support - #24606

Draft
thykel wants to merge 9 commits into
devfrom
observed_versions_PoC
Draft

poc: Full Observed Versions support#24606
thykel wants to merge 9 commits into
devfrom
observed_versions_PoC

Conversation

@thykel

@thykel thykel commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Ticket

What are you trying to accomplish?

Screenshots

What approach did you choose and why?

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

Mirrors #effective_target_versions so that pending, not yet persisted
overrides of the observed version set are visible to readers such as the
APIv3 representer. Unlike the target kind there is no deprecated
single-value column to reconcile, so only the override is considered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thykel
thykel force-pushed the observed_versions_PoC branch 2 times, most recently from 2eeab41 to 821f5cd Compare August 4, 2026 22:54
thykel and others added 3 commits August 5, 2026 01:15
Adds the link, embed and setter to the work package representer and the
matching schema property, whose allowed values come from the contract's
assignable_observed_in_versions (all shared versions, closed ones
included). The attribute is always a collection, so options.multiple is
unconditionally true - there is no single-valued field it stands in for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
observedInVersions is now part of the representation, so a change to an
observed version has to invalidate the cached JSON. The correlated
subquery drops its kind restriction and aggregates the kind alongside the
version, so that moving a version between kinds is detected as well.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sortable and groupable through the same aggregated subqueries the target
versions column uses, restricted to the observed_in kind.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thykel
thykel force-pushed the observed_versions_PoC branch from 821f5cd to a33d392 Compare August 4, 2026 23:17
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./spec/features/work_packages/table/queries/subject_filter_spec.rb[1:1]
🤖 Ask Copilot to investigate

Copy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer.

@copilot The following spec(s) are flaky in CI (first seen on PR #24606, linked for reference only):

- `rspec ./spec/features/work_packages/table/queries/subject_filter_spec.rb[1:1]`

Treat this as a standalone task, unrelated to PR #24606. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24606 or reuse that branch.

Follow the playbook in docs/development/testing/handling-flaky-tests/README.md to find the root cause and fix the underlying race — do not skip, delete, or weaken the spec to make it pass; disabling is a last resort per the playbook, and only with a bug ticket. Verify the fix by running the spec(s) repeatedly (e.g. `script/bulk_run_rspec --run-count 10`).

If you cannot reproduce the flake or are not confident in a fix after reasonable investigation, do not fabricate a change or skip the spec to force CI green. Instead, leave the pull request in draft and document what you tried, the suspected cause, and any leads in its description, then assign @thykel to take over.

Once the fix is verified, title the PR after the spec(s) it fixes, and use the PR description to explain the root cause, how the change resolves it, and the before/after results. Label the PR `flaky-spec`, assign @thykel, and request a review from @thykel.
On every commit, set @thykel as the sole co-author with a `Co-authored-by:` trailer (use their GitHub no-reply email so it links to their account), so it is traceable who dispatched the fix.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends OpenProject’s multi-version infrastructure by adding end-to-end support for “Observed versions” (observedInVersions / observed_in_versions) across API v3 representations and schema, query filters/sorting, journaling, exports (PDF/XLS), and frontend editing.

Changes:

  • Add observedInVersions as a first-class API v3 work package link collection (representer + schema + docs) and include it in cache checksum calculation.
  • Add query support for observed versions (filter, select/sort/group SQL) and wire it into the WorkPackage query filter set.
  • Journal and export observed versions, including a new shared journal formatter for joined version lists and additional eager loading for journal activities.

Reviewed changes

Copilot reviewed 36 out of 36 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
spec/models/work_packages/pdf_export/work_package_to_pdf_spec.rb Updates PDF export expectations to include “Observed versions” in details output.
spec/lib/api/v3/work_packages/eager_loading/cache_checksum_integration_spec.rb Adjusts checksum expectation so observed-in version changes bust the cache.
modules/xls_export/app/models/xls_export/work_package/exporter/xls.rb Eager-loads observed_in_versions for XLS exports.
lib/open_project/journal_formatter/target_versions.rb Refactors TargetVersions formatter to inherit from new JoinedVersions.
lib/open_project/journal_formatter/observed_in_versions.rb Adds journal formatter for observed-in versions.
lib/open_project/journal_formatter/joined_versions.rb Introduces shared formatter for rendering comma-joined version name lists from stored ID strings.
lib/api/v3/work_packages/work_package_representer.rb Exposes observed_in_versions as associated resources/links and adds it to representable attrs order.
lib/api/v3/work_packages/schema/work_package_schema_representer.rb Adds schema entry for observed_in_versions as always-multi-valued collection.
lib/api/v3/work_packages/schema/specific_work_package_schema.rb Delegates assignable_observed_in_versions to contract.
lib/api/v3/work_packages/eager_loading/checksum.rb Extends versions checksum to include all work_package_versions kinds (incl. observed_in).
lib/api/v3/queries/schemas/observed_in_versions_filter_dependency_representer.rb Adds filter dependency representer class for observed-in versions filter.
lib/api/v3/activities/activity_eager_loading_wrapper.rb Switches eager loading from kind-scoped to unified work_package_version_journals.
lib_static/plugins/acts_as_journalized/lib/journal_changes.rb Adds observed_in_versions changeset diffing and refactors change aggregation.
frontend/src/app/shared/components/fields/edit/field-types/versions-edit-field.component.ts Updates documentation to cover both version collections in the versions edit field.
frontend/src/app/shared/components/fields/edit/edit-field.initializer.ts Registers versions edit field for observedInVersions in addition to targetVersions.
frontend/src/app/features/work-packages/components/wp-edit/work-package-changeset.ts Excludes empty targetVersions/observedInVersions link collections on create payloads.
docs/api/apiv3/tags/work_packages.yml Documents observedInVersions in the work packages tag table.
docs/api/apiv3/components/schemas/work_package_write_model.yml Adds observedInVersions to the write model schema docs.
docs/api/apiv3/components/schemas/work_package_schema_model.yml Adds observedInVersions to schema model docs.
docs/api/apiv3/components/schemas/work_package_model.yml Adds observedInVersions to work package model docs + example.
config/locales/en.yml Adds English label for observed_in_versions.
config/initializers/export_formats.rb Registers export formatter for observed_in_versions.
app/services/work_packages/activities_tab/paginator.rb Eager-loads unified work_package_version_journals for activities tab pagination.
app/services/journals/create_service/work_package_version.rb Expands journaling to include observed_in kind.
app/models/work_package/versions.rb Adds observed-in associations and effective_observed_in_versions for pending overrides.
app/models/work_package/journalized.rb Registers observed_in_versions as a formatted journal field.
app/models/work_package/exports/formatters/observed_in_versions.rb Adds export formatter producing observed-in version names.
app/models/queries/work_packages/selects/property_select.rb Adds observed-in versions select with SQL for sorting and grouping.
app/models/queries/work_packages/filter/version_filter.rb Switches to generic FilterOnWorkPackageVersionsMixin and defines version_kind.
app/models/queries/work_packages/filter/target_versions_filter.rb Switches to generic mixin and defines version_kind.
app/models/queries/work_packages/filter/observed_in_versions_filter.rb Adds observed-in versions query filter using generic mixin.
app/models/queries/work_packages/filter/filter_on_work_package_versions_mixin.rb Generalizes target-version-only mixin to kind-based version filtering.
app/models/queries/work_packages.rb Registers the new ObservedInVersions filter in WorkPackage queries.
app/models/journal.rb Registers ObservedInVersions formatter and derives kind-scoped version journal arrays in memory.
app/models/activities/fetcher.rb Updates activity journal eager loading to use unified version journals association.
app/contracts/work_packages/base_contract.rb Adds attribute contract entry for observed_in_versions with assignability validation.

Comment thread lib/open_project/journal_formatter/observed_in_versions.rb
thykel and others added 5 commits August 5, 2026 16:13
FilterOnTargetVersionsMixin becomes FilterOnWorkPackageVersionsMixin,
parameterised over the work_package_versions kind its including filter
declares, so the new filter shares the operator handling of the existing
ones. The APIv3 filter dependency representer is a subclass of the version
one, whose allowed values are identical; a dedicated class is needed only
because the factory resolves representers by filter class name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds observed_in to the journaled kinds, an observed_in_version_journals
association to read them back, and a journal change that diffs the whole
set as one value - the same shape the target versions change uses. The
rendering logic both formatters share moves into a JoinedVersions base
class. Activity fetchers eager load the new association alongside the
target one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds the export formatter that renders the version names, so the column
works in CSV, XLS and PDF exports as well as in workPackageValue macros,
and eager loads the association in the XLS exporter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Registers the attribute with VersionsEditFieldComponent so it gets the
project grouping and inline version creation the target versions field
has. The empty collection stripping on create, which the API rejects as an
empty array of links, is generalised over both version attributes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thykel
thykel force-pushed the observed_versions_PoC branch from a33d392 to f938344 Compare August 5, 2026 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants