mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-15 11:58:34 +08:00
fix(skill): preserve skillContent/configJson on security scan write-back (issue #45)
SkillPackageResolver.persistScanOutcome built a fresh SkillEntity with only id + scan fields, then called updateById. SkillEntity declares six columns with @TableField(updateStrategy = FieldStrategy.ALWAYS) — name_zh, name_en, config_json, source_code, skill_content, security_scan_result — so the ALWAYS strategy emits UPDATE statements that write NULL to every one of those columns not set on the partial entity. Effect: every security re-scan that produced a status/findings change silently wiped skill_content, config_json, source_code, name_zh, name_en on the row. After importing a custom skill, the first scan tick destroyed the imported content. Fix: switch to LambdaUpdateWrapper so the UPDATE only touches the three scan columns we actually want to change. Other skillMapper.updateById call sites (SkillService, BuiltinSkillSeedService) pass DB-hydrated existing entities and are unaffected. Reported and diagnosed by @pipima9950-glitch in issue #45.
This commit is contained in:
parent
977e181949
commit
d20b440ce5
@ -1,5 +1,6 @@
|
|||||||
package vip.mate.skill.runtime;
|
package vip.mate.skill.runtime;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -106,17 +107,24 @@ public class SkillPackageResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SkillEntity update = new SkillEntity();
|
// Whitelist via LambdaUpdateWrapper (issue #45): SkillEntity has
|
||||||
update.setId(entity.getId());
|
// several @TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||||
update.setSecurityScanStatus(newStatus);
|
// columns (skill_content, config_json, source_code, name_zh,
|
||||||
update.setSecurityScanResult(newJson);
|
// name_en, security_scan_result). Calling updateById with a
|
||||||
update.setSecurityScanTime(LocalDateTime.now());
|
// partial entity would tell MyBatis Plus to write NULL to every
|
||||||
skillMapper.updateById(update);
|
// ALWAYS column not set on the partial — wiping the imported
|
||||||
|
// skill content on every scan write-back.
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
skillMapper.update(null, new LambdaUpdateWrapper<SkillEntity>()
|
||||||
|
.eq(SkillEntity::getId, entity.getId())
|
||||||
|
.set(SkillEntity::getSecurityScanStatus, newStatus)
|
||||||
|
.set(SkillEntity::getSecurityScanResult, newJson)
|
||||||
|
.set(SkillEntity::getSecurityScanTime, now));
|
||||||
// Keep the in-memory entity coherent with the DB so the next
|
// Keep the in-memory entity coherent with the DB so the next
|
||||||
// resolve in the same tick doesn't redundantly write again.
|
// resolve in the same tick doesn't redundantly write again.
|
||||||
entity.setSecurityScanStatus(newStatus);
|
entity.setSecurityScanStatus(newStatus);
|
||||||
entity.setSecurityScanResult(newJson);
|
entity.setSecurityScanResult(newJson);
|
||||||
entity.setSecurityScanTime(update.getSecurityScanTime());
|
entity.setSecurityScanTime(now);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Failed to persist scan outcome for skill '{}': {}", entity.getName(), e.getMessage());
|
log.warn("Failed to persist scan outcome for skill '{}': {}", entity.getName(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user