create-yss-spec 3.4.10 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/src/api/_sync-service.js +111 -18
- package/src/cli/args.js +1 -0
- package/src/cli/help.js +10 -1
- package/src/cli/index.js +3 -0
- package/src/cli/prompts.js +5 -1
- package/src/cli/router.js +2 -0
- package/src/commands/attach.js +12 -2
- package/src/commands/init.js +2 -0
- package/src/commands/skills.js +253 -0
- package/src/commands/sync.js +3 -0
- package/src/family-identity.js +1 -1
- package/src/template/asset-runtime.js +220 -0
- package/src/template/distribution-runtime.js +165 -0
- package/src/template/instance-runtime.js +76 -29
- package/src/template/ownership-policy.js +17 -1
- package/src/template/prune-planner.js +6 -1
- package/src/template/sync-planner.js +3 -0
- package/src/template/verification-runtime.js +56 -1
- package/src/validation/metadata.js +24 -1
- package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
- package/template/.agents/skills/yss-cache/SKILL.md +6 -5
- package/template/.agents/skills/yss-cache/references/annotations.md +3 -1
- package/template/.agents/skills/yss-cache/references/architecture.md +4 -2
- package/template/.agents/skills/yss-cache/references/configuration.md +6 -3
- package/template/.agents/skills/yss-cache/references/jetcache.md +21 -0
- package/template/.agents/skills/yss-cache/references/redis-fallback.md +5 -3
- package/template/.agents/skills/yss-cache/references/verification.md +10 -4
- package/template/.agents/skills/yss-cache/scripts/verify-cache-component.sh +26 -20
- package/template/.agents/skills/yss-distributed-id/SKILL.md +14 -58
- package/template/.agents/skills/yss-distributed-id/agents/openai.yaml +2 -2
- package/template/.agents/skills/yss-distributed-id/references/README.md +11 -47
- package/template/.agents/skills/yss-mybatis/SKILL.md +14 -2
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +5 -4
- package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +8 -8
- package/template/.agents/skills/yss-prototype-stage/SKILL.md +2 -2
- package/template/.agents/skills/yss-repository/SKILL.md +1 -0
- package/template/.codex/skills/yss-cache/SKILL.md +6 -5
- package/template/.codex/skills/yss-cache/references/annotations.md +3 -1
- package/template/.codex/skills/yss-cache/references/architecture.md +4 -2
- package/template/.codex/skills/yss-cache/references/configuration.md +6 -3
- package/template/.codex/skills/yss-cache/references/jetcache.md +21 -0
- package/template/.codex/skills/yss-cache/references/redis-fallback.md +5 -3
- package/template/.codex/skills/yss-cache/references/verification.md +10 -4
- package/template/.codex/skills/yss-cache/scripts/verify-cache-component.sh +26 -20
- package/template/.codex/skills/yss-distributed-id/SKILL.md +14 -58
- package/template/.codex/skills/yss-distributed-id/agents/openai.yaml +2 -2
- package/template/.codex/skills/yss-distributed-id/references/README.md +11 -47
- package/template/.codex/skills/yss-mybatis/SKILL.md +14 -2
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +5 -4
- package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +8 -8
- package/template/.codex/skills/yss-prototype-stage/SKILL.md +2 -2
- package/template/.codex/skills/yss-repository/SKILL.md +1 -0
- package/template/.cursor/skills/yss-cache/SKILL.md +6 -5
- package/template/.cursor/skills/yss-cache/references/annotations.md +3 -1
- package/template/.cursor/skills/yss-cache/references/architecture.md +4 -2
- package/template/.cursor/skills/yss-cache/references/configuration.md +6 -3
- package/template/.cursor/skills/yss-cache/references/jetcache.md +21 -0
- package/template/.cursor/skills/yss-cache/references/redis-fallback.md +5 -3
- package/template/.cursor/skills/yss-cache/references/verification.md +10 -4
- package/template/.cursor/skills/yss-cache/scripts/verify-cache-component.sh +26 -20
- package/template/.cursor/skills/yss-distributed-id/SKILL.md +14 -58
- package/template/.cursor/skills/yss-distributed-id/agents/openai.yaml +2 -2
- package/template/.cursor/skills/yss-distributed-id/references/README.md +11 -47
- package/template/.cursor/skills/yss-mybatis/SKILL.md +14 -2
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +5 -4
- package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +8 -8
- package/template/.cursor/skills/yss-prototype-stage/SKILL.md +2 -2
- package/template/.cursor/skills/yss-repository/SKILL.md +1 -0
- package/template/.pi/skills/yss-cache/SKILL.md +6 -5
- package/template/.pi/skills/yss-cache/references/annotations.md +3 -1
- package/template/.pi/skills/yss-cache/references/architecture.md +4 -2
- package/template/.pi/skills/yss-cache/references/configuration.md +6 -3
- package/template/.pi/skills/yss-cache/references/jetcache.md +21 -0
- package/template/.pi/skills/yss-cache/references/redis-fallback.md +5 -3
- package/template/.pi/skills/yss-cache/references/verification.md +10 -4
- package/template/.pi/skills/yss-cache/scripts/verify-cache-component.sh +26 -20
- package/template/.pi/skills/yss-distributed-id/SKILL.md +14 -58
- package/template/.pi/skills/yss-distributed-id/agents/openai.yaml +2 -2
- package/template/.pi/skills/yss-distributed-id/references/README.md +11 -47
- package/template/.pi/skills/yss-mybatis/SKILL.md +14 -2
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +5 -4
- package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +8 -8
- package/template/.pi/skills/yss-prototype-stage/SKILL.md +2 -2
- package/template/.pi/skills/yss-repository/SKILL.md +1 -0
- package/template/README.md +2 -5
- package/template/docs/agents/skill-migrations.md +4 -0
- package/template/docs/agents/yss-skill-registry.yaml +7 -6
- package/template/docs/design/README.md +0 -1
- package/template/docs/design/design.md +2 -2
- package/template/docs/design/templates/interaction-spec-template.md +1 -1
- package/template/docs/engineering/evidence/aliyun-artifact-resolution.json +446 -0
- package/template/scripts/design-md +2 -0
- package/template/scripts/lib/design-md.mjs +230 -0
- package/template/scripts/lib/skill-registry.mjs +9 -2
- package/template/scripts/lib/skill-supply-chain.mjs +33 -14
- package/template/scripts/verify-project-instance +11 -10
- package/template/skills-lock.json +11 -26
- package/template.manifest.json +18 -3
- package/template.snapshot.json +5 -5
- package/template/.agents/skills/grill-me/SKILL.md +0 -7
- package/template/.agents/skills/grill-me/agents/openai.yaml +0 -5
- package/template/.agents/skills/yss-distributed-id/assets/AutoIdInterceptor.java +0 -246
- package/template/.agents/skills/yss-distributed-id/assets/EnableDistributedId.java +0 -25
- package/template/.agents/skills/yss-distributed-id/assets/LeafConf.java +0 -36
- package/template/.codex/skills/grill-me/SKILL.md +0 -7
- package/template/.codex/skills/grill-me/agents/openai.yaml +0 -5
- package/template/.codex/skills/yss-distributed-id/assets/AutoIdInterceptor.java +0 -246
- package/template/.codex/skills/yss-distributed-id/assets/EnableDistributedId.java +0 -25
- package/template/.codex/skills/yss-distributed-id/assets/LeafConf.java +0 -36
- package/template/.cursor/skills/grill-me/SKILL.md +0 -7
- package/template/.cursor/skills/grill-me/agents/openai.yaml +0 -5
- package/template/.cursor/skills/yss-distributed-id/assets/AutoIdInterceptor.java +0 -246
- package/template/.cursor/skills/yss-distributed-id/assets/EnableDistributedId.java +0 -25
- package/template/.cursor/skills/yss-distributed-id/assets/LeafConf.java +0 -36
- package/template/.pi/skills/grill-me/SKILL.md +0 -7
- package/template/.pi/skills/grill-me/agents/openai.yaml +0 -5
- package/template/.pi/skills/yss-distributed-id/assets/AutoIdInterceptor.java +0 -246
- package/template/.pi/skills/yss-distributed-id/assets/EnableDistributedId.java +0 -25
- package/template/.pi/skills/yss-distributed-id/assets/LeafConf.java +0 -36
- package/template/docs/agents/yss-plugin-dependency-contract.md +0 -45
- package/template/docs/api/.gitkeep +0 -0
- package/template/docs/api/specs/.gitkeep +0 -0
- package/template/docs/architecture/.gitkeep +0 -0
- package/template/docs/design/facts/antdv-next/1.5.2/cli-help.txt +0 -38
- package/template/docs/design/facts/antdv-next/1.5.2/component-list.json +0 -434
- package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/demo-basic.json +0 -7
- package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/info.json +0 -246
- package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/semantic.json +0 -40
- package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/token.json +0 -32
- package/template/docs/design/facts/antdv-next/1.5.2/components/Button/demo-basic.json +0 -7
- package/template/docs/design/facts/antdv-next/1.5.2/components/Button/info.json +0 -190
- package/template/docs/design/facts/antdv-next/1.5.2/components/Button/semantic.json +0 -20
- package/template/docs/design/facts/antdv-next/1.5.2/components/Button/token.json +0 -256
- package/template/docs/design/facts/antdv-next/1.5.2/components/Input/demo-basic.json +0 -7
- package/template/docs/design/facts/antdv-next/1.5.2/components/Input/info.json +0 -460
- package/template/docs/design/facts/antdv-next/1.5.2/components/Input/semantic.json +0 -70
- package/template/docs/design/facts/antdv-next/1.5.2/components/Input/token.json +0 -123
- package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/demo-basic.json +0 -7
- package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/info.json +0 -646
- package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/semantic.json +0 -50
- package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/token.json +0 -130
- package/template/docs/design/facts/antdv-next/1.5.2/components/Select/demo-basic.json +0 -7
- package/template/docs/design/facts/antdv-next/1.5.2/components/Select/info.json +0 -640
- package/template/docs/design/facts/antdv-next/1.5.2/components/Select/semantic.json +0 -70
- package/template/docs/design/facts/antdv-next/1.5.2/components/Select/token.json +0 -172
- package/template/docs/design/facts/antdv-next/1.5.2/components/Table/demo-basic.json +0 -7
- package/template/docs/design/facts/antdv-next/1.5.2/components/Table/info.json +0 -1010
- package/template/docs/design/facts/antdv-next/1.5.2/components/Table/semantic.json +0 -70
- package/template/docs/design/facts/antdv-next/1.5.2/components/Table/token.json +0 -263
- package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/demo-basic.json +0 -7
- package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/info.json +0 -321
- package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/semantic.json +0 -25
- package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/token.json +0 -25
- package/template/docs/design/facts/antdv-next/1.5.2/design-md.json +0 -3
- package/template/docs/design/facts/antdv-next/1.5.2/manifest.json +0 -215
- package/template/docs/design/facts/antdv-next/1.5.2/resolution-probe.json +0 -5
- package/template/docs/design/prototypes/.gitkeep +0 -1
- package/template/docs/implementation/.gitkeep +0 -1
- package/template/docs/plan/IDEATION.md +0 -96
- package/template/docs/process/PDCA-SCRUM.md +0 -10
- package/template/docs/process/harness-executive-blueprint.md +0 -10
- package/template/docs/releases/.gitkeep +0 -1
- package/template/docs/requirements/README.md +0 -85
- package/template/docs/requirements/tickets/.gitkeep +0 -1
- package/template/docs/templates/agent-brief-template.md +0 -46
- package/template/docs/templates/architecture-proposal-template.md +0 -18
- package/template/docs/templates/implementation-plan-template.md +0 -16
- package/template/docs/templates/implementation-routing-template.md +0 -350
- package/template/docs/templates/requirement-freeze-template.md +0 -63
- package/template/docs/templates/risk-register-template.md +0 -11
- package/template/docs/templates/user-story-template.md +0 -20
- package/template/docs/testing/README.md +0 -110
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
package com.yss.cloud.sankuai.mybatis;
|
|
2
|
-
|
|
3
|
-
import com.baomidou.mybatisplus.annotation.IdType;
|
|
4
|
-
import com.baomidou.mybatisplus.annotation.TableId;
|
|
5
|
-
import com.baomidou.mybatisplus.annotation.TableName;
|
|
6
|
-
import com.yss.cloud.exception.BizException;
|
|
7
|
-
import com.yss.cloud.sankuai.CosidSegmentContextHelper;
|
|
8
|
-
import com.yss.cloud.sankuai.GenerationTypeSeq;
|
|
9
|
-
import com.yss.cloud.sankuai.SegmentContextHelper;
|
|
10
|
-
import com.yss.cloud.sankuai.SnowflakeContextHelper;
|
|
11
|
-
import lombok.extern.slf4j.Slf4j;
|
|
12
|
-
import org.apache.commons.lang3.StringUtils;
|
|
13
|
-
import org.apache.ibatis.binding.BindingException;
|
|
14
|
-
import org.apache.ibatis.binding.MapperMethod;
|
|
15
|
-
import org.apache.ibatis.executor.statement.StatementHandler;
|
|
16
|
-
import org.apache.ibatis.mapping.BoundSql;
|
|
17
|
-
import org.apache.ibatis.plugin.Interceptor;
|
|
18
|
-
import org.apache.ibatis.plugin.Intercepts;
|
|
19
|
-
import org.apache.ibatis.plugin.Invocation;
|
|
20
|
-
import org.apache.ibatis.plugin.Signature;
|
|
21
|
-
import org.springframework.util.ObjectUtils;
|
|
22
|
-
import org.springframework.util.ReflectionUtils;
|
|
23
|
-
|
|
24
|
-
import javax.persistence.Entity;
|
|
25
|
-
import javax.persistence.GeneratedValue;
|
|
26
|
-
import javax.persistence.Table;
|
|
27
|
-
import java.lang.reflect.Field;
|
|
28
|
-
import java.sql.Connection;
|
|
29
|
-
import java.util.*;
|
|
30
|
-
|
|
31
|
-
@Intercepts(
|
|
32
|
-
{
|
|
33
|
-
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
|
|
34
|
-
}
|
|
35
|
-
)
|
|
36
|
-
@Slf4j
|
|
37
|
-
public class AutoIdInterceptor implements Interceptor {
|
|
38
|
-
|
|
39
|
-
@Override
|
|
40
|
-
public Object intercept(Invocation invocation) throws Throwable {
|
|
41
|
-
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
|
|
42
|
-
BoundSql boundSql = statementHandler.getBoundSql();
|
|
43
|
-
String boundSqlStr = boundSql.getSql();
|
|
44
|
-
if (StringUtils.startsWithIgnoreCase(StringUtils.trim(boundSqlStr),"INSERT")){
|
|
45
|
-
processInsertStatement(statementHandler);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return invocation.proceed();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 1.处理插入的情况
|
|
53
|
-
*
|
|
54
|
-
* @apiNote 1.处理新增insert
|
|
55
|
-
* @param statementHandler 句柄
|
|
56
|
-
*/
|
|
57
|
-
private void processInsertStatement(StatementHandler statementHandler) {
|
|
58
|
-
BoundSql boundSql = statementHandler.getBoundSql();
|
|
59
|
-
Object parameterObject = boundSql.getParameterObject();
|
|
60
|
-
|
|
61
|
-
if (parameterObject != null) {
|
|
62
|
-
processParameterObject(parameterObject);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 处理参数对象
|
|
68
|
-
*
|
|
69
|
-
* @apiNote 2.处理参数对象 mapper->entityList,plus->param1
|
|
70
|
-
* @param parameterObject 参数对象
|
|
71
|
-
*/
|
|
72
|
-
private void processParameterObject(Object parameterObject) {
|
|
73
|
-
if (parameterObject instanceof MapperMethod.ParamMap<?>){
|
|
74
|
-
// 获取批量实体对象,若为空则为single 参数对象
|
|
75
|
-
Object entityList = null;
|
|
76
|
-
try {
|
|
77
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("entityList");
|
|
78
|
-
}catch (BindingException e){
|
|
79
|
-
log.warn("non entityList. info -> {}",e.getLocalizedMessage());
|
|
80
|
-
}
|
|
81
|
-
// 兼容mybatis默认参数 集合的场景
|
|
82
|
-
if (ObjectUtils.isEmpty(entityList)){
|
|
83
|
-
try {
|
|
84
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("collection");
|
|
85
|
-
}catch (BindingException e){
|
|
86
|
-
log.warn("non entityList & non collection. info -> {}",e.getLocalizedMessage());
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// 兼容mybatis默认参数 数组的场景
|
|
90
|
-
if (ObjectUtils.isEmpty(entityList)){
|
|
91
|
-
try {
|
|
92
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("array");
|
|
93
|
-
}catch (BindingException e){
|
|
94
|
-
log.warn("non entityList & non collection & non array. info -> {}",e.getLocalizedMessage());
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (ObjectUtils.isEmpty(entityList)){
|
|
98
|
-
try {
|
|
99
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("param1");
|
|
100
|
-
}catch (BindingException e){
|
|
101
|
-
log.error("non param1. info -> {}",e.getLocalizedMessage());
|
|
102
|
-
throw new BizException("FeignAutoIdInterceptor run error");
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (entityList instanceof List) {
|
|
106
|
-
// 批量插入
|
|
107
|
-
List<?> el = (List<?>) entityList;
|
|
108
|
-
for (Object entity : el) {
|
|
109
|
-
processEntity(entity);
|
|
110
|
-
}
|
|
111
|
-
} else if (entityList.getClass().isArray()) {
|
|
112
|
-
// 批量插入
|
|
113
|
-
Object[] array = (Object[]) entityList;
|
|
114
|
-
for (Object entity : array) {
|
|
115
|
-
processEntity(entity);
|
|
116
|
-
}
|
|
117
|
-
}else {
|
|
118
|
-
// 单独插入
|
|
119
|
-
processEntity(entityList);
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
// 单独插入
|
|
123
|
-
processEntity(parameterObject);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* 3.处理对象实体
|
|
129
|
-
*
|
|
130
|
-
* @apiNote 3.处理对象实体
|
|
131
|
-
* @param entity 对象实体
|
|
132
|
-
*/
|
|
133
|
-
private void processEntity(Object entity) {
|
|
134
|
-
Class<?> entityClass = entity.getClass();
|
|
135
|
-
if (isEntityClass(entityClass)) {
|
|
136
|
-
autoIdSet(entity);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 4.自动为实体设置id
|
|
142
|
-
*
|
|
143
|
-
* @apiNote 4.自动为实体设置id
|
|
144
|
-
* @param entity 对象实体
|
|
145
|
-
*/
|
|
146
|
-
private void autoIdSet(Object entity) {
|
|
147
|
-
Class<?> entityClass = entity.getClass();
|
|
148
|
-
List<Field> fields = getAllFields(entityClass);
|
|
149
|
-
for (Field field : fields) {
|
|
150
|
-
|
|
151
|
-
if (field.isAnnotationPresent(GeneratedValue.class)||
|
|
152
|
-
field.isAnnotationPresent(TableId.class)) {
|
|
153
|
-
processGeneratedValue(entity, field);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* 5.设置id字段
|
|
160
|
-
*
|
|
161
|
-
* @param entity 实体对象
|
|
162
|
-
* @param field id字段
|
|
163
|
-
*/
|
|
164
|
-
private void processGeneratedValue(Object entity, Field field) {
|
|
165
|
-
String genIdType = getGenIdType(field);
|
|
166
|
-
|
|
167
|
-
String tableName = getTableName(entity);
|
|
168
|
-
|
|
169
|
-
if (Objects.nonNull(genIdType)&&
|
|
170
|
-
Objects.nonNull(SegmentContextHelper.LeafConf())&&
|
|
171
|
-
SegmentContextHelper.LeafConf().isLeafSegmentEnable()&&
|
|
172
|
-
(genIdType.equals(GenerationTypeSeq.SEGMENT) || genIdType.equals(IdType.AUTO.name()) || genIdType.equals(IdType.ASSIGN_ID.name()))) {
|
|
173
|
-
long idValue = SegmentContextHelper.nextId(tableName);
|
|
174
|
-
setFieldValue(entity, field, idValue);
|
|
175
|
-
} else if (Objects.nonNull(genIdType)&&
|
|
176
|
-
Objects.nonNull(SnowflakeContextHelper.LeafConf())&&
|
|
177
|
-
SnowflakeContextHelper.LeafConf().isLeafSnowflakeEnable()
|
|
178
|
-
&&genIdType.equals(GenerationTypeSeq.SNOWFLAKE) ) {
|
|
179
|
-
long idValue = SnowflakeContextHelper.nextId();
|
|
180
|
-
setFieldValue(entity, field, idValue);
|
|
181
|
-
} else if (Objects.nonNull(genIdType)&&
|
|
182
|
-
(genIdType.equals(GenerationTypeSeq.UUID)|| genIdType.equals(IdType.ASSIGN_UUID.name()))) {
|
|
183
|
-
String idValue = UUID.randomUUID().toString();
|
|
184
|
-
setFieldValue(entity, field, idValue);
|
|
185
|
-
} else if (Objects.nonNull(genIdType) &&
|
|
186
|
-
genIdType.equals(GenerationTypeSeq.COSID_SEGMENT)) {
|
|
187
|
-
long idValue = CosidSegmentContextHelper.nextId(tableName);
|
|
188
|
-
setFieldValue(entity, field, idValue);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
private void setFieldValue(Object entity, Field field, Object value) {
|
|
193
|
-
field.setAccessible(true);
|
|
194
|
-
// 如果value为null,则ID生成服务不可用,使用默认规则替代;有值则覆盖
|
|
195
|
-
if(!Objects.isNull(value)) {
|
|
196
|
-
if (field.getType() == String.class) {
|
|
197
|
-
ReflectionUtils.setField(field,entity,String.valueOf(value));
|
|
198
|
-
} else if (field.getType() == Integer.class) {
|
|
199
|
-
ReflectionUtils.setField(field,entity,Integer.valueOf(String.valueOf(value)));
|
|
200
|
-
} else {
|
|
201
|
-
ReflectionUtils.setField(field,entity,value);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
private boolean isEntityClass(Class<?> clazz) {
|
|
207
|
-
return clazz.isAnnotationPresent(Entity.class)||clazz.isAnnotationPresent(TableName.class);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
private String getTableName(Object entity){
|
|
211
|
-
Table table = entity.getClass().getAnnotation(Table.class);
|
|
212
|
-
if (Objects.nonNull(table)){
|
|
213
|
-
return table.name();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
TableName tableName = entity.getClass().getAnnotation(TableName.class);
|
|
217
|
-
|
|
218
|
-
if (Objects.nonNull(tableName)){
|
|
219
|
-
return tableName.value();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
private static List<Field> getAllFields(Class<?> clazz) {
|
|
225
|
-
List<Field> fields = new ArrayList<>();
|
|
226
|
-
while (clazz != null) {
|
|
227
|
-
Collections.addAll(fields, clazz.getDeclaredFields());
|
|
228
|
-
clazz = clazz.getSuperclass();
|
|
229
|
-
}
|
|
230
|
-
return fields;
|
|
231
|
-
}
|
|
232
|
-
private String getGenIdType(Field field){
|
|
233
|
-
GeneratedValue generatedValueAnnotation = field.getAnnotation(GeneratedValue.class);
|
|
234
|
-
|
|
235
|
-
if (Objects.nonNull(generatedValueAnnotation)){
|
|
236
|
-
return generatedValueAnnotation.generator();
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
TableId tableId = field.getAnnotation(TableId.class);
|
|
240
|
-
|
|
241
|
-
if (Objects.nonNull(tableId)){
|
|
242
|
-
return tableId.type().name();
|
|
243
|
-
}
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
package com.yss.cloud;
|
|
2
|
-
|
|
3
|
-
import com.yss.cloud.sankuai.config.LeafConf;
|
|
4
|
-
import com.yss.cloud.sankuai.config.LeafDataSourceConfiguration;
|
|
5
|
-
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
6
|
-
import org.springframework.context.annotation.Import;
|
|
7
|
-
|
|
8
|
-
import java.lang.annotation.*;
|
|
9
|
-
|
|
10
|
-
@Target({ElementType.TYPE})
|
|
11
|
-
@Retention(RetentionPolicy.RUNTIME)
|
|
12
|
-
@Documented
|
|
13
|
-
@Inherited
|
|
14
|
-
@Import({LeafDataSourceConfiguration.class, EnableDistributedImportSelector.class})
|
|
15
|
-
@EnableConfigurationProperties(LeafConf.class)
|
|
16
|
-
public @interface EnableDistributedId {
|
|
17
|
-
/**
|
|
18
|
-
* 默认自动装载leaf配置,设置默认启用状态
|
|
19
|
-
*/
|
|
20
|
-
boolean autoRegister() default true;
|
|
21
|
-
/**
|
|
22
|
-
* 是否启用cosid模式
|
|
23
|
-
*/
|
|
24
|
-
boolean cosid() default false;
|
|
25
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
package com.yss.cloud.sankuai.config;
|
|
2
|
-
|
|
3
|
-
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
4
|
-
|
|
5
|
-
@ConfigurationProperties(prefix = "spring.leaf", ignoreInvalidFields = true)
|
|
6
|
-
public class LeafConf {
|
|
7
|
-
private boolean leafSegmentEnable;
|
|
8
|
-
private boolean leafSnowflakeEnable;
|
|
9
|
-
|
|
10
|
-
public boolean isLeafSegmentEnable() {
|
|
11
|
-
return leafSegmentEnable;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public void setLeafSegmentEnable(boolean leafSegmentEnable) {
|
|
15
|
-
this.leafSegmentEnable = leafSegmentEnable;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
public boolean isLeafSnowflakeEnable() {
|
|
19
|
-
return leafSnowflakeEnable;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public void setLeafSnowflakeEnable(boolean leafSnowflakeEnable) {
|
|
23
|
-
this.leafSnowflakeEnable = leafSnowflakeEnable;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@Override
|
|
27
|
-
public String toString() {
|
|
28
|
-
return "LeafConf{"
|
|
29
|
-
+ "leafSegmentEnable="
|
|
30
|
-
+ leafSegmentEnable
|
|
31
|
-
+ ", leafSnowflakeEnable="
|
|
32
|
-
+ leafSnowflakeEnable
|
|
33
|
-
+ ", leafSnowflakePort="
|
|
34
|
-
+ '}';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
package com.yss.cloud.sankuai.mybatis;
|
|
2
|
-
|
|
3
|
-
import com.baomidou.mybatisplus.annotation.IdType;
|
|
4
|
-
import com.baomidou.mybatisplus.annotation.TableId;
|
|
5
|
-
import com.baomidou.mybatisplus.annotation.TableName;
|
|
6
|
-
import com.yss.cloud.exception.BizException;
|
|
7
|
-
import com.yss.cloud.sankuai.CosidSegmentContextHelper;
|
|
8
|
-
import com.yss.cloud.sankuai.GenerationTypeSeq;
|
|
9
|
-
import com.yss.cloud.sankuai.SegmentContextHelper;
|
|
10
|
-
import com.yss.cloud.sankuai.SnowflakeContextHelper;
|
|
11
|
-
import lombok.extern.slf4j.Slf4j;
|
|
12
|
-
import org.apache.commons.lang3.StringUtils;
|
|
13
|
-
import org.apache.ibatis.binding.BindingException;
|
|
14
|
-
import org.apache.ibatis.binding.MapperMethod;
|
|
15
|
-
import org.apache.ibatis.executor.statement.StatementHandler;
|
|
16
|
-
import org.apache.ibatis.mapping.BoundSql;
|
|
17
|
-
import org.apache.ibatis.plugin.Interceptor;
|
|
18
|
-
import org.apache.ibatis.plugin.Intercepts;
|
|
19
|
-
import org.apache.ibatis.plugin.Invocation;
|
|
20
|
-
import org.apache.ibatis.plugin.Signature;
|
|
21
|
-
import org.springframework.util.ObjectUtils;
|
|
22
|
-
import org.springframework.util.ReflectionUtils;
|
|
23
|
-
|
|
24
|
-
import javax.persistence.Entity;
|
|
25
|
-
import javax.persistence.GeneratedValue;
|
|
26
|
-
import javax.persistence.Table;
|
|
27
|
-
import java.lang.reflect.Field;
|
|
28
|
-
import java.sql.Connection;
|
|
29
|
-
import java.util.*;
|
|
30
|
-
|
|
31
|
-
@Intercepts(
|
|
32
|
-
{
|
|
33
|
-
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
|
|
34
|
-
}
|
|
35
|
-
)
|
|
36
|
-
@Slf4j
|
|
37
|
-
public class AutoIdInterceptor implements Interceptor {
|
|
38
|
-
|
|
39
|
-
@Override
|
|
40
|
-
public Object intercept(Invocation invocation) throws Throwable {
|
|
41
|
-
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
|
|
42
|
-
BoundSql boundSql = statementHandler.getBoundSql();
|
|
43
|
-
String boundSqlStr = boundSql.getSql();
|
|
44
|
-
if (StringUtils.startsWithIgnoreCase(StringUtils.trim(boundSqlStr),"INSERT")){
|
|
45
|
-
processInsertStatement(statementHandler);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return invocation.proceed();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 1.处理插入的情况
|
|
53
|
-
*
|
|
54
|
-
* @apiNote 1.处理新增insert
|
|
55
|
-
* @param statementHandler 句柄
|
|
56
|
-
*/
|
|
57
|
-
private void processInsertStatement(StatementHandler statementHandler) {
|
|
58
|
-
BoundSql boundSql = statementHandler.getBoundSql();
|
|
59
|
-
Object parameterObject = boundSql.getParameterObject();
|
|
60
|
-
|
|
61
|
-
if (parameterObject != null) {
|
|
62
|
-
processParameterObject(parameterObject);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 处理参数对象
|
|
68
|
-
*
|
|
69
|
-
* @apiNote 2.处理参数对象 mapper->entityList,plus->param1
|
|
70
|
-
* @param parameterObject 参数对象
|
|
71
|
-
*/
|
|
72
|
-
private void processParameterObject(Object parameterObject) {
|
|
73
|
-
if (parameterObject instanceof MapperMethod.ParamMap<?>){
|
|
74
|
-
// 获取批量实体对象,若为空则为single 参数对象
|
|
75
|
-
Object entityList = null;
|
|
76
|
-
try {
|
|
77
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("entityList");
|
|
78
|
-
}catch (BindingException e){
|
|
79
|
-
log.warn("non entityList. info -> {}",e.getLocalizedMessage());
|
|
80
|
-
}
|
|
81
|
-
// 兼容mybatis默认参数 集合的场景
|
|
82
|
-
if (ObjectUtils.isEmpty(entityList)){
|
|
83
|
-
try {
|
|
84
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("collection");
|
|
85
|
-
}catch (BindingException e){
|
|
86
|
-
log.warn("non entityList & non collection. info -> {}",e.getLocalizedMessage());
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// 兼容mybatis默认参数 数组的场景
|
|
90
|
-
if (ObjectUtils.isEmpty(entityList)){
|
|
91
|
-
try {
|
|
92
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("array");
|
|
93
|
-
}catch (BindingException e){
|
|
94
|
-
log.warn("non entityList & non collection & non array. info -> {}",e.getLocalizedMessage());
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (ObjectUtils.isEmpty(entityList)){
|
|
98
|
-
try {
|
|
99
|
-
entityList = ((MapperMethod.ParamMap<?>) parameterObject).get("param1");
|
|
100
|
-
}catch (BindingException e){
|
|
101
|
-
log.error("non param1. info -> {}",e.getLocalizedMessage());
|
|
102
|
-
throw new BizException("FeignAutoIdInterceptor run error");
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (entityList instanceof List) {
|
|
106
|
-
// 批量插入
|
|
107
|
-
List<?> el = (List<?>) entityList;
|
|
108
|
-
for (Object entity : el) {
|
|
109
|
-
processEntity(entity);
|
|
110
|
-
}
|
|
111
|
-
} else if (entityList.getClass().isArray()) {
|
|
112
|
-
// 批量插入
|
|
113
|
-
Object[] array = (Object[]) entityList;
|
|
114
|
-
for (Object entity : array) {
|
|
115
|
-
processEntity(entity);
|
|
116
|
-
}
|
|
117
|
-
}else {
|
|
118
|
-
// 单独插入
|
|
119
|
-
processEntity(entityList);
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
// 单独插入
|
|
123
|
-
processEntity(parameterObject);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* 3.处理对象实体
|
|
129
|
-
*
|
|
130
|
-
* @apiNote 3.处理对象实体
|
|
131
|
-
* @param entity 对象实体
|
|
132
|
-
*/
|
|
133
|
-
private void processEntity(Object entity) {
|
|
134
|
-
Class<?> entityClass = entity.getClass();
|
|
135
|
-
if (isEntityClass(entityClass)) {
|
|
136
|
-
autoIdSet(entity);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 4.自动为实体设置id
|
|
142
|
-
*
|
|
143
|
-
* @apiNote 4.自动为实体设置id
|
|
144
|
-
* @param entity 对象实体
|
|
145
|
-
*/
|
|
146
|
-
private void autoIdSet(Object entity) {
|
|
147
|
-
Class<?> entityClass = entity.getClass();
|
|
148
|
-
List<Field> fields = getAllFields(entityClass);
|
|
149
|
-
for (Field field : fields) {
|
|
150
|
-
|
|
151
|
-
if (field.isAnnotationPresent(GeneratedValue.class)||
|
|
152
|
-
field.isAnnotationPresent(TableId.class)) {
|
|
153
|
-
processGeneratedValue(entity, field);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* 5.设置id字段
|
|
160
|
-
*
|
|
161
|
-
* @param entity 实体对象
|
|
162
|
-
* @param field id字段
|
|
163
|
-
*/
|
|
164
|
-
private void processGeneratedValue(Object entity, Field field) {
|
|
165
|
-
String genIdType = getGenIdType(field);
|
|
166
|
-
|
|
167
|
-
String tableName = getTableName(entity);
|
|
168
|
-
|
|
169
|
-
if (Objects.nonNull(genIdType)&&
|
|
170
|
-
Objects.nonNull(SegmentContextHelper.LeafConf())&&
|
|
171
|
-
SegmentContextHelper.LeafConf().isLeafSegmentEnable()&&
|
|
172
|
-
(genIdType.equals(GenerationTypeSeq.SEGMENT) || genIdType.equals(IdType.AUTO.name()) || genIdType.equals(IdType.ASSIGN_ID.name()))) {
|
|
173
|
-
long idValue = SegmentContextHelper.nextId(tableName);
|
|
174
|
-
setFieldValue(entity, field, idValue);
|
|
175
|
-
} else if (Objects.nonNull(genIdType)&&
|
|
176
|
-
Objects.nonNull(SnowflakeContextHelper.LeafConf())&&
|
|
177
|
-
SnowflakeContextHelper.LeafConf().isLeafSnowflakeEnable()
|
|
178
|
-
&&genIdType.equals(GenerationTypeSeq.SNOWFLAKE) ) {
|
|
179
|
-
long idValue = SnowflakeContextHelper.nextId();
|
|
180
|
-
setFieldValue(entity, field, idValue);
|
|
181
|
-
} else if (Objects.nonNull(genIdType)&&
|
|
182
|
-
(genIdType.equals(GenerationTypeSeq.UUID)|| genIdType.equals(IdType.ASSIGN_UUID.name()))) {
|
|
183
|
-
String idValue = UUID.randomUUID().toString();
|
|
184
|
-
setFieldValue(entity, field, idValue);
|
|
185
|
-
} else if (Objects.nonNull(genIdType) &&
|
|
186
|
-
genIdType.equals(GenerationTypeSeq.COSID_SEGMENT)) {
|
|
187
|
-
long idValue = CosidSegmentContextHelper.nextId(tableName);
|
|
188
|
-
setFieldValue(entity, field, idValue);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
private void setFieldValue(Object entity, Field field, Object value) {
|
|
193
|
-
field.setAccessible(true);
|
|
194
|
-
// 如果value为null,则ID生成服务不可用,使用默认规则替代;有值则覆盖
|
|
195
|
-
if(!Objects.isNull(value)) {
|
|
196
|
-
if (field.getType() == String.class) {
|
|
197
|
-
ReflectionUtils.setField(field,entity,String.valueOf(value));
|
|
198
|
-
} else if (field.getType() == Integer.class) {
|
|
199
|
-
ReflectionUtils.setField(field,entity,Integer.valueOf(String.valueOf(value)));
|
|
200
|
-
} else {
|
|
201
|
-
ReflectionUtils.setField(field,entity,value);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
private boolean isEntityClass(Class<?> clazz) {
|
|
207
|
-
return clazz.isAnnotationPresent(Entity.class)||clazz.isAnnotationPresent(TableName.class);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
private String getTableName(Object entity){
|
|
211
|
-
Table table = entity.getClass().getAnnotation(Table.class);
|
|
212
|
-
if (Objects.nonNull(table)){
|
|
213
|
-
return table.name();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
TableName tableName = entity.getClass().getAnnotation(TableName.class);
|
|
217
|
-
|
|
218
|
-
if (Objects.nonNull(tableName)){
|
|
219
|
-
return tableName.value();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
private static List<Field> getAllFields(Class<?> clazz) {
|
|
225
|
-
List<Field> fields = new ArrayList<>();
|
|
226
|
-
while (clazz != null) {
|
|
227
|
-
Collections.addAll(fields, clazz.getDeclaredFields());
|
|
228
|
-
clazz = clazz.getSuperclass();
|
|
229
|
-
}
|
|
230
|
-
return fields;
|
|
231
|
-
}
|
|
232
|
-
private String getGenIdType(Field field){
|
|
233
|
-
GeneratedValue generatedValueAnnotation = field.getAnnotation(GeneratedValue.class);
|
|
234
|
-
|
|
235
|
-
if (Objects.nonNull(generatedValueAnnotation)){
|
|
236
|
-
return generatedValueAnnotation.generator();
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
TableId tableId = field.getAnnotation(TableId.class);
|
|
240
|
-
|
|
241
|
-
if (Objects.nonNull(tableId)){
|
|
242
|
-
return tableId.type().name();
|
|
243
|
-
}
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
package com.yss.cloud;
|
|
2
|
-
|
|
3
|
-
import com.yss.cloud.sankuai.config.LeafConf;
|
|
4
|
-
import com.yss.cloud.sankuai.config.LeafDataSourceConfiguration;
|
|
5
|
-
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
6
|
-
import org.springframework.context.annotation.Import;
|
|
7
|
-
|
|
8
|
-
import java.lang.annotation.*;
|
|
9
|
-
|
|
10
|
-
@Target({ElementType.TYPE})
|
|
11
|
-
@Retention(RetentionPolicy.RUNTIME)
|
|
12
|
-
@Documented
|
|
13
|
-
@Inherited
|
|
14
|
-
@Import({LeafDataSourceConfiguration.class, EnableDistributedImportSelector.class})
|
|
15
|
-
@EnableConfigurationProperties(LeafConf.class)
|
|
16
|
-
public @interface EnableDistributedId {
|
|
17
|
-
/**
|
|
18
|
-
* 默认自动装载leaf配置,设置默认启用状态
|
|
19
|
-
*/
|
|
20
|
-
boolean autoRegister() default true;
|
|
21
|
-
/**
|
|
22
|
-
* 是否启用cosid模式
|
|
23
|
-
*/
|
|
24
|
-
boolean cosid() default false;
|
|
25
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
package com.yss.cloud.sankuai.config;
|
|
2
|
-
|
|
3
|
-
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
4
|
-
|
|
5
|
-
@ConfigurationProperties(prefix = "spring.leaf", ignoreInvalidFields = true)
|
|
6
|
-
public class LeafConf {
|
|
7
|
-
private boolean leafSegmentEnable;
|
|
8
|
-
private boolean leafSnowflakeEnable;
|
|
9
|
-
|
|
10
|
-
public boolean isLeafSegmentEnable() {
|
|
11
|
-
return leafSegmentEnable;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public void setLeafSegmentEnable(boolean leafSegmentEnable) {
|
|
15
|
-
this.leafSegmentEnable = leafSegmentEnable;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
public boolean isLeafSnowflakeEnable() {
|
|
19
|
-
return leafSnowflakeEnable;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public void setLeafSnowflakeEnable(boolean leafSnowflakeEnable) {
|
|
23
|
-
this.leafSnowflakeEnable = leafSnowflakeEnable;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@Override
|
|
27
|
-
public String toString() {
|
|
28
|
-
return "LeafConf{"
|
|
29
|
-
+ "leafSegmentEnable="
|
|
30
|
-
+ leafSegmentEnable
|
|
31
|
-
+ ", leafSnowflakeEnable="
|
|
32
|
-
+ leafSnowflakeEnable
|
|
33
|
-
+ ", leafSnowflakePort="
|
|
34
|
-
+ '}';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# YSS 插件依赖契约
|
|
2
|
-
|
|
3
|
-
## 目的
|
|
4
|
-
|
|
5
|
-
YSS Codex 插件可以随插件包提供角色 Harness skill,但不拥有目标项目的共享 skill。共享 skill 的权威内容仍是目标项目的 `.agents/skills`,投影、来源和 hash 由目标项目的 `skills-lock.json` 与 `docs/agents/yss-skill-registry.yaml` 管理。
|
|
6
|
-
|
|
7
|
-
插件依赖文件位于插件根目录 `.yss-plugin/dependencies.yaml`,用于声明插件需要的角色契约,而不是复制 `core_skills` 清单。
|
|
8
|
-
|
|
9
|
-
```yaml
|
|
10
|
-
schema_version: 1
|
|
11
|
-
plugin: yss-backend-harness
|
|
12
|
-
requires:
|
|
13
|
-
- role_id: role.backend-engineer
|
|
14
|
-
registry: docs/agents/digital-human-roles.yaml
|
|
15
|
-
minimum_contract_version: 1
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 校验规则
|
|
19
|
-
|
|
20
|
-
1. 插件导入时只校验 `dependencies.yaml` 的结构、插件名和 `schema_version`。
|
|
21
|
-
2. 插件调用前必须校验目标项目 `yss-project.yaml`,且 `repository_mode` 合法。
|
|
22
|
-
3. 目标项目必须存在依赖声明中的角色,且 `contract_version` 不低于 `minimum_contract_version`。
|
|
23
|
-
4. 角色的 `core_skills` 由目标项目的 `digital-human-roles.yaml` 动态解析;插件不得维护第二份清单。
|
|
24
|
-
5. 共享 skill 必须通过 `yss-skill-registry.yaml`、`skills-lock.json` 和目标 Agent projection 校验。
|
|
25
|
-
6. 缺少角色、版本不兼容、skill 缺失、来源或 hash 漂移、投影不完整时,插件必须返回 `blocked`,不得降级执行。
|
|
26
|
-
7. 插件不得自动写入 `.agents/skills`、`skills-lock.json` 或任何 Agent projection;修复应回路由到目标项目维护流程。
|
|
27
|
-
|
|
28
|
-
## 运行时结果
|
|
29
|
-
|
|
30
|
-
依赖不满足时至少返回:
|
|
31
|
-
|
|
32
|
-
```yaml
|
|
33
|
-
status: blocked
|
|
34
|
-
blocking_signals: [missing-role]
|
|
35
|
-
diagnostics:
|
|
36
|
-
plugin: yss-backend-harness
|
|
37
|
-
required_role: role.backend-engineer
|
|
38
|
-
next_route: install-or-sync-target-project-skills
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
`blocking_signals` 可使用 `repository-identity-invalid`、`missing-role`、`incompatible-contract-version`、`missing-skill`、`skill-source-drift`、`skill-hash-drift` 和 `skill-projection-incomplete`。
|
|
42
|
-
|
|
43
|
-
## 版本策略
|
|
44
|
-
|
|
45
|
-
依赖文件 schema 只保证同一主版本向后兼容。插件的 `minimum_contract_version` 是硬门槛;`tested_with` 等兼容性信息只能作为提示,不能替代目标项目的契约版本校验。
|
|
File without changes
|
|
File without changes
|
|
File without changes
|