fix: reconcile progress inventory before sync
This commit is contained in:
parent
aa451f03db
commit
f544edd82c
@ -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) {
|
function git(repoRoot, args) {
|
||||||
const result = spawnSync('git', args, { cwd: repoRoot, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 })
|
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()}`)
|
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({
|
body: JSON.stringify({
|
||||||
context: apiContext,
|
context: apiContext,
|
||||||
project_description: env.PROJECT_DESCRIPTION,
|
project_description: env.PROJECT_DESCRIPTION,
|
||||||
|
inventory_check: buildInventoryCheck(await apiRequest(apiBase, env.API_KEY, `/projects/${project.projectId}/progress-sync`)),
|
||||||
commits: [commit],
|
commits: [commit],
|
||||||
updates: [update],
|
updates: [update],
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import test from 'node:test'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
buildApiContext,
|
buildApiContext,
|
||||||
|
buildInventoryCheck,
|
||||||
classifyCommit,
|
classifyCommit,
|
||||||
makeFeatureCatalogKey,
|
makeFeatureCatalogKey,
|
||||||
makeIdempotencyKey,
|
makeIdempotencyKey,
|
||||||
@ -11,6 +12,41 @@ import {
|
|||||||
validateStatusEvidence,
|
validateStatusEvidence,
|
||||||
} from '../../scripts/kaifa-progress-sync.mjs'
|
} 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', () => {
|
test('keeps Git author filtering separate from the board developer identity', () => {
|
||||||
assert.deepEqual(buildApiContext({
|
assert.deepEqual(buildApiContext({
|
||||||
OWNER_EMAIL: '549727955@qq.com',
|
OWNER_EMAIL: '549727955@qq.com',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user