@@ -649,13 +649,14 @@ def update_frameworks(self):
649649 requirement_nodes = new_framework ["requirement_nodes" ]
650650 framework_dict = {** new_framework }
651651 del framework_dict ["requirement_nodes" ]
652+ framework_dict ["urn" ] = framework_dict ["urn" ].lower ()
652653 prev_fw = Framework .objects .filter (urn = framework_dict ["urn" ]).first ()
653654 prev_min = getattr (prev_fw , "min_score" , None )
654655 prev_max = getattr (prev_fw , "max_score" , None )
655656 prev_def = getattr (prev_fw , "scores_definition" , None )
656657
657658 new_framework , _ = Framework .objects .update_or_create (
658- urn = new_framework ["urn" ],
659+ urn = framework_dict ["urn" ],
659660 defaults = framework_dict ,
660661 create_defaults = {
661662 ** self .referential_object_dict ,
@@ -820,23 +821,68 @@ def update_frameworks(self):
820821 for k , v in requirement_node .items ()
821822 if k not in ["urn" , "depth" , "reference_controls" , "threats" ]
822823 }
824+ if (
825+ "parent_urn" in requirement_node_dict
826+ and requirement_node_dict ["parent_urn" ]
827+ ):
828+ requirement_node_dict ["parent_urn" ] = requirement_node_dict [
829+ "parent_urn"
830+ ].lower ()
823831 requirement_node_dict ["order_id" ] = order_id
824832 order_id += 1
825- all_fields_to_update .update (requirement_node_dict .keys ())
833+
834+ # Fields safe to update on existing requirement nodes.
835+ # Excludes structural fields (parent_urn) that
836+ # would break the framework hierarchy.
837+ UPDATABLE_FIELDS = {
838+ "name" ,
839+ "description" ,
840+ "annotation" ,
841+ "typical_evidence" ,
842+ "translations" ,
843+ "assessable" ,
844+ "implementation_groups" ,
845+ "questions" ,
846+ "weight" ,
847+ "importance" ,
848+ "order_id" ,
849+ }
826850
827851 if urn in existing_requirement_node_objects :
828852 requirement_node_object = existing_requirement_node_objects [urn ]
829- for key , value in requirement_node_dict .items ():
853+ update_dict = {
854+ k : v
855+ for k , v in requirement_node_dict .items ()
856+ if k in UPDATABLE_FIELDS
857+ }
858+ for key , value in update_dict .items ():
830859 setattr (requirement_node_object , key , value )
860+ all_fields_to_update .update (update_dict .keys ())
831861 requirement_node_objects_to_update .append (
832862 requirement_node_object
833863 )
834864 else :
835- requirement_node_object = RequirementNode .objects .create (
836- urn = urn ,
837- framework = new_framework ,
838- ** self .referential_object_dict ,
839- ** requirement_node_dict ,
865+ existing_node = RequirementNode .objects .filter (urn = urn ).first ()
866+ if (
867+ existing_node
868+ and existing_node .framework_id != new_framework .id
869+ ):
870+ raise ValidationError ("requirementNodeUrnConflict" )
871+ requirement_node_object , _ = (
872+ RequirementNode .objects .update_or_create (
873+ urn = urn ,
874+ defaults = {
875+ "framework" : new_framework ,
876+ ** self .referential_object_dict ,
877+ ** requirement_node_dict ,
878+ },
879+ create_defaults = {
880+ "framework" : new_framework ,
881+ ** self .referential_object_dict ,
882+ ** self .i18n_object_dict ,
883+ ** requirement_node_dict ,
884+ },
885+ )
840886 )
841887 for ca in compliance_assessments :
842888 requirement_assessment_objects_to_create .append (
0 commit comments