mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-27 11:14:59 +00:00
fix(compat): prefer published legacy slug candidates
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
parent
32d5de7c44
commit
46336a2576
2 changed files with 66 additions and 8 deletions
|
|
@ -27,6 +27,10 @@ import org.springframework.stereotype.Service;
|
|||
@Service
|
||||
public class CompatSkillLookupService {
|
||||
|
||||
private static final int LEGACY_SLUG_PUBLISHED_SCORE = 1_000;
|
||||
private static final int LEGACY_SLUG_PUBLIC_SCORE = 100;
|
||||
private static final int LEGACY_SLUG_GLOBAL_SCORE = 10;
|
||||
|
||||
private final SkillRepository skillRepository;
|
||||
private final NamespaceRepository namespaceRepository;
|
||||
private final SkillVersionRepository skillVersionRepository;
|
||||
|
|
@ -60,14 +64,8 @@ public class CompatSkillLookupService {
|
|||
: namespaceRepository.findByIdIn(namespaceIds).stream()
|
||||
.collect(Collectors.toMap(Namespace::getId, Function.identity()));
|
||||
Skill skill = skills.stream()
|
||||
.min(Comparator.<Skill>comparingInt(s -> {
|
||||
Namespace ns = namespacesById.get(s.getNamespaceId());
|
||||
int score = 0;
|
||||
if (s.getVisibility() == SkillVisibility.PUBLIC) score += 100;
|
||||
if (ns != null && ns.getType() == NamespaceType.GLOBAL) score += 50;
|
||||
if (s.getLatestVersionId() != null) score += 10;
|
||||
return -score;
|
||||
}).thenComparing(Skill::getId))
|
||||
.min(Comparator.<Skill>comparingInt(s -> -legacySlugCandidateScore(s, namespacesById))
|
||||
.thenComparing(Skill::getId))
|
||||
.orElse(skills.get(0));
|
||||
Namespace namespace = namespacesById.get(skill.getNamespaceId());
|
||||
if (namespace == null) {
|
||||
|
|
@ -115,6 +113,16 @@ public class CompatSkillLookupService {
|
|||
return skillVersionRepository.findById(skill.getLatestVersionId());
|
||||
}
|
||||
|
||||
private static int legacySlugCandidateScore(Skill skill, Map<Long, Namespace> namespacesById) {
|
||||
Namespace namespace = namespacesById.get(skill.getNamespaceId());
|
||||
int score = 0;
|
||||
// Bare-slug CLI resolution should prefer installable candidates before namespace defaults.
|
||||
if (skill.getLatestVersionId() != null) score += LEGACY_SLUG_PUBLISHED_SCORE;
|
||||
if (skill.getVisibility() == SkillVisibility.PUBLIC) score += LEGACY_SLUG_PUBLIC_SCORE;
|
||||
if (namespace != null && namespace.getType() == NamespaceType.GLOBAL) score += LEGACY_SLUG_GLOBAL_SCORE;
|
||||
return score;
|
||||
}
|
||||
|
||||
private Skill resolveVisibleSkill(Long namespaceId, String slug, String currentUserId) {
|
||||
try {
|
||||
return skillSlugResolutionService.resolve(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import static org.mockito.Mockito.when;
|
|||
import com.iflytek.skillhub.domain.namespace.Namespace;
|
||||
import com.iflytek.skillhub.domain.namespace.NamespaceRepository;
|
||||
import com.iflytek.skillhub.domain.namespace.NamespaceRole;
|
||||
import com.iflytek.skillhub.domain.namespace.NamespaceType;
|
||||
import com.iflytek.skillhub.domain.shared.exception.DomainNotFoundException;
|
||||
import com.iflytek.skillhub.domain.skill.Skill;
|
||||
import com.iflytek.skillhub.domain.skill.SkillRepository;
|
||||
|
|
@ -15,6 +16,7 @@ import com.iflytek.skillhub.domain.skill.SkillVersionRepository;
|
|||
import com.iflytek.skillhub.domain.skill.SkillVisibility;
|
||||
import com.iflytek.skillhub.domain.skill.VisibilityChecker;
|
||||
import com.iflytek.skillhub.domain.skill.service.SkillSlugResolutionService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -36,6 +38,40 @@ class CompatSkillLookupServiceTest {
|
|||
visibilityChecker
|
||||
);
|
||||
|
||||
@Test
|
||||
void findByLegacySlug_prefersPublicGlobalPublishedCandidate() {
|
||||
Skill privateTeamSkill = skill(11L, 1L, "demo", SkillVisibility.PRIVATE, 110L);
|
||||
Skill publicTeamSkill = skill(12L, 1L, "demo", SkillVisibility.PUBLIC, 120L);
|
||||
Skill publicGlobalSkill = skill(13L, 2L, "demo", SkillVisibility.PUBLIC, 130L);
|
||||
Namespace teamNamespace = namespace(1L, "team-a", NamespaceType.TEAM);
|
||||
Namespace globalNamespace = namespace(2L, "global", NamespaceType.GLOBAL);
|
||||
|
||||
when(skillRepository.findBySlug("demo"))
|
||||
.thenReturn(List.of(privateTeamSkill, publicTeamSkill, publicGlobalSkill));
|
||||
when(namespaceRepository.findByIdIn(List.of(1L, 2L))).thenReturn(List.of(teamNamespace, globalNamespace));
|
||||
|
||||
CompatSkillLookupService.CompatSkillContext result = service.findByLegacySlug("demo");
|
||||
|
||||
assertThat(result.skill().getId()).isEqualTo(13L);
|
||||
assertThat(result.namespace().getSlug()).isEqualTo("global");
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByLegacySlug_prefersPublishedCandidateOverGlobalDraft() {
|
||||
Skill publicGlobalDraft = skill(21L, 2L, "demo", SkillVisibility.PUBLIC, null);
|
||||
Skill publicTeamPublished = skill(22L, 1L, "demo", SkillVisibility.PUBLIC, 220L);
|
||||
Namespace teamNamespace = namespace(1L, "team-a", NamespaceType.TEAM);
|
||||
Namespace globalNamespace = namespace(2L, "global", NamespaceType.GLOBAL);
|
||||
|
||||
when(skillRepository.findBySlug("demo")).thenReturn(List.of(publicGlobalDraft, publicTeamPublished));
|
||||
when(namespaceRepository.findByIdIn(List.of(2L, 1L))).thenReturn(List.of(globalNamespace, teamNamespace));
|
||||
|
||||
CompatSkillLookupService.CompatSkillContext result = service.findByLegacySlug("demo");
|
||||
|
||||
assertThat(result.skill().getId()).isEqualTo(22L);
|
||||
assertThat(result.namespace().getSlug()).isEqualTo("team-a");
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveVisible_throwsNotFoundWhenCallerCannotAccessSkill() {
|
||||
Namespace namespace = new Namespace("team-a", "Team A", "owner-1");
|
||||
|
|
@ -75,4 +111,18 @@ class CompatSkillLookupServiceTest {
|
|||
|
||||
assertThat(result.skill().getId()).isEqualTo(7L);
|
||||
}
|
||||
|
||||
private static Skill skill(Long id, Long namespaceId, String slug, SkillVisibility visibility, Long latestVersionId) {
|
||||
Skill skill = new Skill(namespaceId, slug, "owner-1", visibility);
|
||||
ReflectionTestUtils.setField(skill, "id", id);
|
||||
skill.setLatestVersionId(latestVersionId);
|
||||
return skill;
|
||||
}
|
||||
|
||||
private static Namespace namespace(Long id, String slug, NamespaceType type) {
|
||||
Namespace namespace = new Namespace(slug, slug, "owner-1");
|
||||
ReflectionTestUtils.setField(namespace, "id", id);
|
||||
namespace.setType(type);
|
||||
return namespace;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue