fix(aihr): harden daily drill fallback profile gate

This commit is contained in:
2026-07-14 13:44:48 +08:00
parent 1730819bfc
commit 187a75f6f6
6 changed files with 33 additions and 3 deletions
@@ -69,6 +69,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -79,6 +80,8 @@ import java.util.concurrent.ConcurrentMap;
@Service
public class AihrPracticeSeedService {
private static final Set<String> LEGACY_DAILY_DRILL_PROFILES = Set.of("dev", "local");
private static final String TENANT_ID = "000000";
private static final Map<String, String> REGENERATE_STYLE_INSTRUCTIONS = Map.of(
"serious", "语气更严肃、直接指出问题,明确告诉员工哪里不到位和下一句该怎么补。",
@@ -217,6 +220,8 @@ public class AihrPracticeSeedService {
private final TransactionTemplate pilotExportTransaction;
@Value("${aihr.practice.allow-legacy-daily-drill-fallback:${AIHR_PRACTICE_ALLOW_LEGACY_DAILY_DRILL_FALLBACK:false}}")
private boolean allowLegacyDailyDrillFallback;
@Value("${spring.profiles.active:}")
private String activeProfiles;
private volatile boolean practiceTableReady;
private volatile boolean assignmentTableReady;
private volatile boolean scenarioTableReady;
@@ -1847,13 +1852,27 @@ public class AihrPracticeSeedService {
// Formal production data must provide hire_date. The record-count fallback is
// intentionally opt-in for the local Demo only; it must not infer employment
// tenure from training activity in a pilot or production tenant.
return isLegacyDailyDrillEligible(allowLegacyDailyDrillFallback, extPartyId, countMobileRecords(extPartyId));
return isLegacyDailyDrillEligible(
isLegacyDailyDrillFallbackEnabled(allowLegacyDailyDrillFallback, activeProfiles),
extPartyId,
countMobileRecords(extPartyId)
);
}
static boolean isLegacyDailyDrillEligible(boolean allowFallback, String extPartyId, int mobileRecordCount) {
return allowFallback && extPartyId != null && !extPartyId.isBlank() && mobileRecordCount < 3;
}
static boolean isLegacyDailyDrillFallbackEnabled(boolean configured, String profiles) {
if (!configured || profiles == null || profiles.isBlank()) {
return false;
}
return java.util.Arrays.stream(profiles.split(","))
.map(String::trim)
.filter(profile -> !profile.isEmpty())
.allMatch(LEGACY_DAILY_DRILL_PROFILES::contains);
}
private Optional<LocalDate> findHireDate(String extPartyId) {
List<LocalDate> hireDates = jdbcTemplate.query("""
SELECT hire_date
@@ -128,6 +128,15 @@ public class AihrPracticeSeedServiceTest {
assertFalse(AihrPracticeSeedService.isLegacyDailyDrillEligible(true, "", 0));
}
@Test
public void legacyDailyDrillFallbackIsLimitedToLocalProfiles() {
assertTrue(AihrPracticeSeedService.isLegacyDailyDrillFallbackEnabled(true, "dev"));
assertTrue(AihrPracticeSeedService.isLegacyDailyDrillFallbackEnabled(true, "local"));
assertFalse(AihrPracticeSeedService.isLegacyDailyDrillFallbackEnabled(true, "prod"));
assertFalse(AihrPracticeSeedService.isLegacyDailyDrillFallbackEnabled(true, "dev,prod"));
assertFalse(AihrPracticeSeedService.isLegacyDailyDrillFallbackEnabled(false, "dev"));
}
@Test
public void dailyDrillAnswerDoesNotOverwriteCompletedAttempt() throws Exception {
String source = Files.readString(Path.of("src/main/java/org/dromara/aihr/service/AihrPracticeSeedService.java"));