openxiangda-devkit-core 2.10.0 → 2.12.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.
@@ -2441,7 +2441,7 @@ function validateCapabilityDeclarations(appCode, declarations, diagnostics) {
2441
2441
  diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_CAPABILITY_DECLARATION_INVALID', '显式 capability 必须属于当前应用、code 唯一,并声明 backend/ui kind 与 name', path));
2442
2442
  }
2443
2443
  if (platformCapabilityCodes(appCode).has(code)) {
2444
- diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_PLATFORM_CAPABILITY_RESERVED', '平台 capability 由平台保留 catalog 提供,应用不能重复声明', `${path}.code`));
2444
+ diagnostics.push(diagnostic('APP_CONFIG_AUTHZ_PLATFORM_CAPABILITY_RESERVED', '平台 capability 由平台保留 catalog 提供,应用不能重复声明', `${path}.code`, `删除 capabilities 里的该声明,直接在角色中引用即可,例如 roles: [{ code: 'admin', capabilities: [directoryRead] }],其中 directoryRead = app:${appCode}:directory:read`));
2445
2445
  }
2446
2446
  seen.add(code);
2447
2447
  });
@@ -2649,7 +2649,7 @@ function validateBackendOperations(rawOperations, declaredResources, declaredWor
2649
2649
  Number(ai.timeoutMs) < 100 ||
2650
2650
  Number(ai.timeoutMs) > 30000)) ||
2651
2651
  aiKeys.some(key => !allowedAiKeys.has(key))) {
2652
- diagnostics.push(diagnostic('APP_CONFIG_BACKEND_OPERATION_AI_INVALID', 'AI 操作必须显式声明名称、说明、风险、现有资源、副作用和有界执行策略;GET 只能只读,写操作必须确认', `${path}.ai`));
2652
+ diagnostics.push(diagnostic('APP_CONFIG_BACKEND_OPERATION_AI_INVALID', 'AI 操作必须显式声明名称、说明、风险、现有资源、副作用和有界执行策略;GET 只能只读,写操作必须确认', `${path}.ai`, '写操作的 ai.sideEffects 至少列一条具体副作用,例如 sideEffects: [\'更新报修单状态为处理中\', \'写入一条派工记录\'];resources 必须引用已声明资源(1-16 个)'));
2653
2653
  }
2654
2654
  }
2655
2655
  codes.add(code);
@@ -3730,6 +3730,12 @@ export function resourceReadPolicy(input) {
3730
3730
  }
3731
3731
  export function materializeDataResource(appCode, declaration) {
3732
3732
  const capabilities = resourceCapabilityCodes(appCode, declaration.code);
3733
+ // audit.read: true 是声明糖:绑定本资源的 read 能力。
3734
+ const auditRead = declaration.audit === undefined || declaration.audit.read === false
3735
+ ? false
3736
+ : declaration.audit.read === true
3737
+ ? [capabilities.read]
3738
+ : [...declaration.audit.read];
3733
3739
  const mutationOwner = declaration.mutationOwner || 'native';
3734
3740
  const nativeMutations = mutationOwner === 'native';
3735
3741
  const generated = {
@@ -3890,7 +3896,7 @@ export function materializeDataResource(appCode, declaration) {
3890
3896
  },
3891
3897
  ])),
3892
3898
  ...(declaration.audit === undefined ? {} : Object.fromEntries(DATA_AUDIT_METADATA_FIELDS.map(code => [code, {
3893
- read: declaration.audit.read === false ? [] : [...declaration.audit.read],
3899
+ read: auditRead === false ? [] : [...auditRead],
3894
3900
  }]))),
3895
3901
  },
3896
3902
  };
@@ -3960,10 +3966,10 @@ export function validateAppDeclaration(value) {
3960
3966
  const read = audit.read;
3961
3967
  if (!resource.audit || typeof resource.audit !== 'object' || Array.isArray(resource.audit) ||
3962
3968
  Object.keys(audit).some(key => key !== 'read') ||
3963
- (read !== false && (!Array.isArray(read) || read.length < 1 || read.length > 20 ||
3969
+ (read !== false && read !== true && (!Array.isArray(read) || read.length < 1 || read.length > 20 ||
3964
3970
  read.some(value => typeof value !== 'string' || !value.trim()) || new Set(read).size !== read.length))) {
3965
3971
  auditValid = false;
3966
- diagnostics.push(diagnostic('APP_CONFIG_DATA_AUDIT_READ_INVALID', 'audit.read 必须为 false 或不重复的非空 capability 数组(最多 20 项)', `${resourcePath}.audit`));
3972
+ diagnostics.push(diagnostic('APP_CONFIG_DATA_AUDIT_READ_INVALID', 'audit.read 必须为 true(绑定资源读能力)、false 或不重复的非空 capability 数组(最多 20 项)', `${resourcePath}.audit`, `audit: { read: true } 会把审计读取绑定到本资源的 read 能力;需要更细粒度时写能力数组,例如 audit: { read: ['app:${appCode}:data:<resource>:read'] }`));
3967
3973
  }
3968
3974
  }
3969
3975
  const mutationOwner = string(resource.mutationOwner) || 'native';