From audit #297 (U4). PartAuthorView role assignment is a free-text TextField("Role name") — typo-prone and unconstrained, and it allows role rows for submeshes the generated GLB doesn't have. Replace with a picker over the fixed #266 vocabulary (Base, Accent 1, Accent 2, Glass, Metal, Sign) and bound role rows by the actual submesh count of the generated GLB. Matches #302's own acceptance text ('role picker, never a colour picker'). Data-correctness fix; if #326's redesigned asset screen lands first, it absorbs this widget.
From audit #297 (U4).
PartAuthorViewrole assignment is a free-textTextField("Role name")— typo-prone and unconstrained, and it allows role rows for submeshes the generated GLB doesn't have. Replace with a picker over the fixed #266 vocabulary (Base, Accent 1, Accent 2, Glass, Metal, Sign) and bound role rows by the actual submesh count of the generated GLB. Matches #302's own acceptance text ('role picker, never a colour picker'). Data-correctness fix; if #326's redesigned asset screen lands first, it absorbs this widget.