Skip to content

feat(product): editable platform/lifecycle/origin lookup tables - #15869

Open
Maffooch wants to merge 4 commits into
devfrom
oss-customizable-asset-dropdowns
Open

feat(product): editable platform/lifecycle/origin lookup tables#15869
Maffooch wants to merge 4 commits into
devfrom
oss-customizable-asset-dropdowns

Conversation

@Maffooch

@Maffooch Maffooch commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Description

Makes the Asset (Product) platform, lifecycle and origin fields customer-editable. The three fixed CharField(choices=...) enums become ForeignKeys to new editable lookup tables (Product_Platform, Product_Lifecycle, Product_Origin), seeded from the current values and managed under Settings > Configuration (and the classic UI), the same way Environments already work. business_criticality is intentionally left unchanged, because its values drive prioritization.

The API keeps the same string wire format via SlugRelatedField(slug_field="value"), so existing integrations, imports and exports send and receive exactly the same strings as before. A value that is not a known option is rejected, matching the old ChoiceField behavior.

New package dojo/product_attributes/ holds the models, admin, /api/v2 viewsets, classic-UI CRUD and configuration permissions. Migration 0297_customizable_asset_attributes creates and seeds the three tables and converts the fields to foreign keys in one node. The conversion is pghistory-safe: it drops and recreates the row triggers around the data copy, converts the mirrored productevent columns the same way, and runs SET CONSTRAINTS ALL IMMEDIATE after the backfill to get past the deferred-FK "pending trigger events" check. Existing values are preserved, and any stored value not present in the seed set gets an option row created for it so nothing is lost.

Test results

Added unittests/test_product_attributes.py: the models and their seeded defaults, the /api/v2 CRUD endpoints (including that value is immutable on update), the Product serializer's value-string round-trip, and the on_delete=RESTRICT guard that blocks deleting an option an asset still uses. The full migration chain applies cleanly on a fresh database.

Documentation

Added docs/content/asset_modelling/PRO__asset_attribute_options.md describing the three editable lists and how to manage them.

Checklist

  • Rebased against the latest dev.
  • Feature submitted against dev.
  • Ruff compliant.
  • Python 3.13 compliant.
  • Documentation included.
  • Migration included (dojo/db_migrations/0297_customizable_asset_attributes.py).
  • Unit tests added.

Convert Product.platform/lifecycle/origin from fixed CharField choices to
ForeignKeys to new editable lookup tables (Product_Platform/Lifecycle/Origin),
seeded from the current values and managed under Settings > Configuration
(and the classic UI). The API keeps the same string wire format via
SlugRelatedField(value), so existing integrations, imports and exports are
unaffected. business_criticality is intentionally unchanged (it drives
prioritization).

Reported via a customer support ticket.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added New Migration Adding a new migration file. Take care when merging. docs unittests ui labels Sep 3, 2026
@Maffooch Maffooch added this to the 3.3.0 milestone Sep 3, 2026
Maffooch and others added 3 commits September 2, 2026 20:49
Sort the import blocks and fix the docstring formatting that ruff 0.16.4
flagged. Also require the model's add/change configuration permission before
saving in the classic-UI add and edit views, matching the existing check on
the delete branch, so a configuration lookup table cannot be created or
modified by an authenticated user without the permission.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…heck

`_resolve_option` in dojo/product/api_v3/routes.py resolves an editable
attribute option (platform/lifecycle/origin) by its immutable value slug during
an asset write. These are global configuration lookup tables with no per-user
authorization scope (like Development_Environment), and the resolver runs only
after the Product_Type_Add_Product / Product_Edit gate, so it is not an object
read. Add it to OBJECTS_ALLOWLIST with that justification.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The V3_FEATURE_LOCATIONS test leg exercises the api_v3 asset tests that the
non-locations leg skips, which surfaced fallout from the CharField->FK change:

- test_apiv3_assets._make_asset built a Product with a raw lifecycle string; it
  now resolves platform/lifecycle/origin value strings to their option rows.
- test_create_happy_path compared Product.lifecycle to "production"; it now
  compares the option's value.
- test_product_attributes loaded dojo_testdata.json, which raises
  EndpointDeprecatedError under V3_FEATURE_LOCATIONS; @versioned_fixtures picks
  the locations testdata there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs New Migration Adding a new migration file. Take care when merging. ui unittests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant