fix: reconcile progress inventory before sync

This commit is contained in:
WuYongJie 2026-09-03 18:22:45 +08:00
parent aa451f03db
commit f544edd82c
2 changed files with 69 additions and 0 deletions

View File

@ -195,6 +195,38 @@ export function validateStatusEvidence(status, options) {
}
}
export function buildInventoryCheck(progressSyncContext, reviewedAt = new Date().toISOString()) {
const currentState = progressSyncContext?.currentState
const modules = currentState?.modules
if (!Array.isArray(modules)) fail('INVENTORY_CONTEXT_MISSING_MODULES')
const items = modules.flatMap((module) => {
if (!module?.moduleId || !module?.name || !Array.isArray(module.features)) fail('INVENTORY_CONTEXT_INVALID_MODULE')
return module.features.map((feature) => {
if (!feature?.featureId || !feature?.name || !feature?.description || !feature?.status || !Number.isFinite(feature?.progressPercent)) {
fail(`INVENTORY_CONTEXT_INVALID_FEATURE:${module.name}/${feature?.name || 'unknown'}`)
}
return {
module_id: module.moduleId,
module_name: module.name,
feature_id: feature.featureId,
feature_name: feature.name,
feature_description: feature.description,
status: feature.status,
progress_percent: feature.progressPercent,
}
})
})
const catalogFeatureCount = currentState?.featureInventoryPolicy?.catalogFeatureCount
if (!Number.isInteger(catalogFeatureCount) || catalogFeatureCount !== items.length) fail('INVENTORY_CONTEXT_COUNT_MISMATCH')
return {
reviewed_at: reviewedAt,
source_inventory_complete: true,
source_feature_count: items.length,
catalog_feature_count: catalogFeatureCount,
items,
}
}
function git(repoRoot, args) {
const result = spawnSync('git', args, { cwd: repoRoot, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 })
if (result.status !== 0) fail(`GIT_FAILED:${args[0]}:${result.stderr.trim()}`)
@ -464,6 +496,7 @@ export async function main(argv = process.argv.slice(2)) {
body: JSON.stringify({
context: apiContext,
project_description: env.PROJECT_DESCRIPTION,
inventory_check: buildInventoryCheck(await apiRequest(apiBase, env.API_KEY, `/projects/${project.projectId}/progress-sync`)),
commits: [commit],
updates: [update],
}),

View File

@ -3,6 +3,7 @@ import test from 'node:test'
import {
buildApiContext,
buildInventoryCheck,
classifyCommit,
makeFeatureCatalogKey,
makeIdempotencyKey,
@ -11,6 +12,41 @@ import {
validateStatusEvidence,
} from '../../scripts/kaifa-progress-sync.mjs'
test('builds the complete inventory check from the freshly fetched catalog state', () => {
const context = {
currentState: {
featureInventoryPolicy: { catalogFeatureCount: 1 },
modules: [{
moduleId: 'module-1',
name: '生产发布与团队协作',
features: [{
featureId: 'feature-1',
name: '钉钉账号登录与绑定',
description: '让现有财务账号通过钉钉完成绑定和登录。',
status: 'done',
progressPercent: 100,
}],
}],
},
}
assert.deepEqual(buildInventoryCheck(context, '2026-09-03T10:00:00.000Z'), {
reviewed_at: '2026-09-03T10:00:00.000Z',
source_inventory_complete: true,
source_feature_count: 1,
catalog_feature_count: 1,
items: [{
module_id: 'module-1',
module_name: '生产发布与团队协作',
feature_id: 'feature-1',
feature_name: '钉钉账号登录与绑定',
feature_description: '让现有财务账号通过钉钉完成绑定和登录。',
status: 'done',
progress_percent: 100,
}],
})
assert.throws(() => buildInventoryCheck({ currentState: { featureInventoryPolicy: { catalogFeatureCount: 1 }, modules: [] } }), /COUNT_MISMATCH/)
})
test('keeps Git author filtering separate from the board developer identity', () => {
assert.deepEqual(buildApiContext({
OWNER_EMAIL: '549727955@qq.com',