/** * 验收格式校验(平台只校验格式,判断由发布方做):checks 必须恰好覆盖全部清单项; * 任一条不通过时动作必须是 reject,全部通过时必须是 accept / select_winner。 * * @param {{ action: 'accept'|'reject'|'select_winner', checks: Array<{ id: string, pass: boolean, reason: string }>, item_keys: string[] }} input * @returns {string|null} 违反规则时返回给调用方的提示;合规返回 null */ export function reviewViolation({ action, checks, item_keys }) { const seen = new Set(checks.map((check) => check.id)) if (seen.size !== checks.length) return 'checks contains the same acceptance item more than once.' const missing = item_keys.filter((key) => !seen.has(key)) if (missing.length > 0) return `checks must cover every acceptance item; missing: ${missing.join(', ')}.` const unknown = checks.filter((check) => !item_keys.includes(check.id)).map((check) => check.id) if (unknown.length > 0) return `checks contains unknown acceptance items: ${unknown.join(', ')}.` const allPass = checks.every((check) => check.pass) switch (action) { case 'accept': case 'select_winner': return allPass ? null : `${action} requires every acceptance item to pass; reject instead.` case 'reject': return allPass ? 'reject requires at least one failed acceptance item; accept instead.' : null default: throw new Error(`Unhandled review action: ${action}`) } }