Skip to content

[FND-209] Remove custom field configuration screen in favor of variants - #24801

Draft
dfriquet wants to merge 6 commits into
devfrom
fnd-209-hide-custom-field-screen-with-variants
Draft

[FND-209] Remove custom field configuration screen in favor of variants#24801
dfriquet wants to merge 6 commits into
devfrom
fnd-209-hide-custom-field-screen-with-variants

Conversation

@dfriquet

@dfriquet dfriquet commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Ticket

https://community.openproject.org/wp/FND-209

Important

Stacked on FND-113 (removes the type_variants feature flag and runs the variant migration). That PR does not exist yet. This one must not merge before it: the code here assumes the flag is gone.

What are you trying to accomplish?

Remove the per-project custom field configuration outright. A type variant's form configuration becomes the only thing that decides which custom fields a work package offers.

Gone:

  • Project settings → Work packages → Custom fields (screen, route, legacy redirect)
  • Administration → Custom fields → ⟨field⟩ → Projects (screen, route, its services and contracts)
  • The select_custom_fields permission, the settings tab, the landing redirect branch, the menu clause, permitted_params
  • The customFields API link in WorkPackageRepresenter, WorkPackageCollectionRepresenter, CreateFormRepresenter, CreateWorkspaceFormRepresenter
  • Every read of custom_fields_projects: all_work_package_custom_fields, custom_fields_activated_in/custom_fields_for_all, the cfp join in OnVisibleTypeAndProject, custom_field_allowed? in the PDF export, custom_field_in_project? in Type::Attributes
  • Every write of it: TypeVariant#activate_custom_fields_in_effective_projects!, Projects::Types::BaseService, UpdateProjectsTypesService

Tightened rather than removed: GET /api/v3/custom_options/:id now requires the caller to see the work packages of a project the field applies to, not merely the project. Project.visible admits every active public project to any logged-in user, so the looser check would have exposed a list field's option labels to anyone guessing an id.

Kept: the custom_fields_projects table and its CustomFieldsProject model, so FND-113's migration can still read the rows it converts. Dropping the table is a follow-up WP, along with is_for_all, which is now inert for work package custom fields — its checkbox and its admin index column are gone, but the column stays because project attributes still use it and the migration reads it to tell a field that was available everywhere from one a project narrowed away.

Screenshots

None.

What approach did you choose and why?

Three commits, in dependency order. Removing the configuration surface, then making the form configuration the sole authority, then stopping the writes. The middle commit is where the behaviour changes, so its spec fallout rides with it.

The migration reads the join table directly. BuildVariantFromProjectService used all_work_package_custom_fields, which is now gone. Had it kept borrowing a helper that stops consulting the table, it would compute an empty exclusion set and convert nothing — silently, since the job just reports every project as unchanged.

Two follow-on effects worth reviewing:

  • WorkPackageCustomField.visible had a short-circuit granting select_custom_fields holders every field. With the permission gone it collapses to on_visible_type_and_project, so visibility always resolves through the form configuration. That reshaped the shared visibility fixtures and both hierarchy API specs, which had used the permission as their authorising condition.
  • Bulk edit widens: editable_custom_fields was (∩ project activations) ∩ (∪ variants' fields) and is now just the union across the selected projects' variants. Tightening it to an intersection would be a real improvement, but it is not "remove project narrowing".

The development seeder was broken, not just made redundant. attribute_groups= never populated custom_fields_types, so the CF DEV% fields were never actually available — the project activation only ever supplied half the condition. extend_group now links them to the form configuration.

Query pickers no longer narrow by project. Scoping them through on_visible_type_and_project(project:) coupled picker contents to User.current and returned empty query results, so they now list every filterable or searchable field — the same behaviour they already had outside a project context. Scoping them by form configuration instead is worth doing, but needs a project-scoped, user-independent scope that does not exist yet.

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc) — no new components or patterns
  • Tested major browsers (Chrome, Firefox, Edge, ...) — via CI's feature suite; manual walkthrough done in Chrome

@github-actions

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./modules/backlogs/spec/features/inbox_column_spec.rb[1:7:1]
  • rspec ./spec/features/projects/create_spec.rb[1:12:3:1]
  • rspec ./spec/features/work_packages/table/queries/parent_field_ranking_spec.rb[1:1]
  • rspec ./spec/features/work_packages/table/switch_types_spec.rb[1:1:1]
  • rspec ./spec/features/work_packages/table/switch_types_spec.rb[1:1:2]
🤖 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 #24801, linked for reference only):

- `rspec ./modules/backlogs/spec/features/inbox_column_spec.rb[1:7:1]`
- `rspec ./spec/features/projects/create_spec.rb[1:12:3:1]`
- `rspec ./spec/features/work_packages/table/queries/parent_field_ranking_spec.rb[1:1]`
- `rspec ./spec/features/work_packages/table/switch_types_spec.rb[1:1:1]`
- `rspec ./spec/features/work_packages/table/switch_types_spec.rb[1:1:2]`

Treat this as a standalone task, unrelated to PR #24801. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24801 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 @dfriquet 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 @dfriquet, and request a review from @dfriquet.
On every commit, set @dfriquet 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.

The shared project-mapping components stay: project attributes subclass them and
now supply the endpoint the deleted work package screen used to provide.
The variant migration switches to reading custom_fields_projects directly, since
nothing else consults it now and those rows are what it converts.
TypeVariant#activate_custom_fields_in_effective_projects! had no callers left and
carried a TODO naming this migration, so it goes with the writers. The development
seeder gains the form configuration link it never had, in place of the activation.
@dfriquet
dfriquet force-pushed the fnd-209-hide-custom-field-screen-with-variants branch from 058b7db to 060d7ee Compare August 18, 2026 11:04
@dfriquet
dfriquet force-pushed the fnd-209-hide-custom-field-screen-with-variants branch from 1aafd23 to 7502992 Compare August 18, 2026 13:58
The table and CustomFieldsProject stay for FND-113's migration to read; its specs
create the rows through that model rather than through an association.
@dfriquet
dfriquet force-pushed the fnd-209-hide-custom-field-screen-with-variants branch from 7502992 to 52a397f Compare August 18, 2026 14:09
Project.visible admits every active public project to any logged-in user, so merely
seeing a project would have been enough to read a list field's option labels through
the API. The scope now accepts the reach its caller needs.
Detaching a mapping is only possible while the project is active, which the removed
permission check enforced on the project's behalf. The feature specs follow the
removal: the deleted settings page object, the checkbox work package fields no
longer carry, and a context whose premise the form configuration replaced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

1 participant