diff --git a/scripts/kaifa-progress-sync.mjs b/scripts/kaifa-progress-sync.mjs index 9612e150..da342efd 100644 --- a/scripts/kaifa-progress-sync.mjs +++ b/scripts/kaifa-progress-sync.mjs @@ -76,6 +76,7 @@ export const FEATURE_RULES = [ }, { key: 'dingtalk-login', priority: 110, moduleName: '生产发布与团队协作', featureName: '钉钉账号登录与绑定', + featureDescription: '通过钉钉 OAuth 完成现有财务账号的首次绑定、后续登录、一次性状态校验和 HTTP 回调接入。', subject: /(?:(?:DingTalk|钉钉).*(?:login|callback|登录|回调)|(?:login|callback|登录|回调).*(?:DingTalk|钉钉))/i, paths: /(?:Auth\/DingTalkLogin|DingTalkIdentity|dingtalk.*callback|config\/dingtalk\.php)/i, }, @@ -129,7 +130,7 @@ export function buildApiContext(env) { export function makeFeatureCatalogKey(repoName, definitions) { const signature = definitions - .map((rule) => `${rule.moduleName}\u0000${rule.featureName}`) + .map((rule) => `${rule.moduleName}\u0000${rule.featureName}\u0000${rule.featureDescription || ''}`) .sort() .join('\u0001') const digest = createHash('sha256').update(signature).digest('hex').slice(0, 16) @@ -333,8 +334,9 @@ export async function main(argv = process.argv.slice(2)) { const requestedSha = values.sha || null const manualModule = values.module || null const manualFeature = values.feature || null - if ((manualModule || manualFeature) && (!requestedSha || !manualModule || !manualFeature)) { - fail('MANUAL_FEATURE_REQUIRES_SHA_MODULE_AND_FEATURE') + const manualFeatureDescription = values['feature-description'] || null + if ((manualModule || manualFeature || manualFeatureDescription) && (!requestedSha || !manualModule || !manualFeature || !manualFeatureDescription)) { + fail('MANUAL_FEATURE_REQUIRES_SHA_MODULE_FEATURE_AND_DESCRIPTION') } if (requestedSha && !/^[0-9a-f]{40}$/i.test(requestedSha)) fail('INVALID_SHA') const limit = values.limit ? Number(values.limit) : Number.POSITIVE_INFINITY @@ -377,6 +379,7 @@ export async function main(argv = process.argv.slice(2)) { key: `manual:${manualModule}:${manualFeature}`, moduleName: manualModule, featureName: manualFeature, + featureDescription: manualFeatureDescription, }, } : classifyCommit(commit.message, commit.changed_files.map((file) => file.path)) @@ -422,7 +425,12 @@ export async function main(argv = process.argv.slice(2)) { body: JSON.stringify({ context: apiContext, project_description: env.PROJECT_DESCRIPTION, - items: definitions.map((rule) => ({ module_name: rule.moduleName, feature_name: rule.featureName, create_module: true })), + items: definitions.map((rule) => ({ + module_name: rule.moduleName, + feature_name: rule.featureName, + feature_description: rule.featureDescription || `实现并验证${rule.featureName}。`, + create_module: true, + })), }), }) const featureIds = new Map() diff --git a/tests/scripts/kaifa-progress-sync.test.mjs b/tests/scripts/kaifa-progress-sync.test.mjs index 676f8697..fde6b35e 100644 --- a/tests/scripts/kaifa-progress-sync.test.mjs +++ b/tests/scripts/kaifa-progress-sync.test.mjs @@ -61,6 +61,7 @@ test('assigns one primary feature and stops on ambiguous feature matches', () => const dingtalkLogin = classifyCommit('feat: add DingTalk account login', ['app/Http/Controllers/Auth/DingTalkLogin.php']).rule assert.equal(dingtalkLogin.key, 'dingtalk-login') assert.equal(dingtalkLogin.featureName, '钉钉账号登录与绑定') + assert.match(dingtalkLogin.featureDescription, /OAuth/) assert.equal( classifyCommit('feat: align taobao reconciliation headers', ['resources/views/store_receivables/zhongcai_reconciliations/partials/embedded-table.blade.php']).rule.key, 'zhongcai-reconciliation',