LayerRepresentativeSelector.java
package com.taxonomy.architecture.service;
import com.taxonomy.catalog.model.TaxonomyNode;
import com.taxonomy.catalog.repository.TaxonomyNodeRepository;
import com.taxonomy.dto.RequirementElementView;
import java.util.*;
/**
* Selects the best node representative for a taxonomy layer during leaf enrichment.
*
* <p>The selection strategy follows a priority order:
* <ol>
* <li>Prefer leaves with depth > 1 (concrete elements).</li>
* <li>If no concrete leaves are available and the root code scores highly enough,
* fall back to the best Level-1 intermediate node as a representative.</li>
* <li>If no intermediates exist either, the layer remains without enrichment.</li>
* </ol>
*
* <p>This prevents root-code-only layers (e.g. CI, BR) from becoming isolated
* islands in the diagram: the intermediate node has a dash in its code, so
* {@code generateImpactRelations()} can create cross-category edges for it.
*/
class LayerRepresentativeSelector {
private final TaxonomyNodeRepository nodeRepository;
LayerRepresentativeSelector(TaxonomyNodeRepository nodeRepository) {
this.nodeRepository = nodeRepository;
}
/**
* Decides whether a candidate node should be accepted for leaf enrichment.
*
* @param node the resolved taxonomy node
* @param rootScore the LLM score for the root code of this layer (0–100)
* @param hasDeepLeafInLayer {@code true} if at least one depth > 1 candidate
* exists in the same root layer
* @return {@code true} if the candidate should be included
*/
boolean shouldInclude(TaxonomyNode node, int rootScore, boolean hasDeepLeafInLayer) {
// Always accept deep leaves (depth > 1)
if (node.getLevel() > 1) {
return true;
}
// Accept level-1 intermediates as fallback when no deep leaves exist
// and the root layer has a meaningful score
if (node.getLevel() == 1 && !hasDeepLeafInLayer
&& rootScore >= RequirementArchitectureViewService.ANCHOR_THRESHOLD_LOW) {
return true;
}
// Skip scaffolding by default
return false;
}
}