feat(product): editable platform/lifecycle/origin lookup tables - #15869
Open
Maffooch wants to merge 4 commits into
Open
feat(product): editable platform/lifecycle/origin lookup tables#15869Maffooch wants to merge 4 commits into
Maffooch wants to merge 4 commits into
Conversation
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>
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Makes the Asset (Product)
platform,lifecycleandoriginfields customer-editable. The three fixedCharField(choices=...)enums becomeForeignKeys 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_criticalityis 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 oldChoiceFieldbehavior.New package
dojo/product_attributes/holds the models, admin,/api/v2viewsets, classic-UI CRUD and configuration permissions. Migration0297_customizable_asset_attributescreates 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 mirroredproducteventcolumns the same way, and runsSET CONSTRAINTS ALL IMMEDIATEafter 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/v2CRUD endpoints (including thatvalueis immutable on update), the Product serializer'svalue-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.mddescribing the three editable lists and how to manage them.Checklist
dev.dev.dojo/db_migrations/0297_customizable_asset_attributes.py).