Files
knowledge-governance/web/src/qaMaster.test.ts
T
姚章浩 533db535f1
build / build (push) Successful in 1m12s
feat(qaops): 接入真实模型补缺任务与总表看板
按已确认需求提供独立安全模型配置、真实探测、正式字典字段评估与原问题译中,持久批次支持只补空白、暂停恢复、有限重试、幂等和逐字段依据。覆盖固定规则、本地语言、组织关联与主表有效看板共用治理侧读模型,保留源生产和冻结历史。

验证:完整 make verify 退出0,702项Go与329项前端通过;默认118项外部/隔离集成明确跳过,另跑完整镜像及组织隔离PG竞态。12并发、输入漂移、过期租约、暂停/恢复及有限重试通过。用户授权的百炼 deepseek-v4.1-flash 完成真实后台与浏览器评估/翻译;552行、16列、11块看板及完整PNG、独立配置页测试/保存、重开恢复和零JS异常通过。仅非业务样本外发,自动处理关闭,原payload不变。

上线前治理库已做导出快照原生备份并真实恢复,60表行数与17个QA表内容哈希一致;不修改DobotAI生产或隧道。本提交时尚未部署,线上验收须独立完成。
2026-10-19 14:29:49 +08:00

66 lines
2.9 KiB
TypeScript

import { afterEach, expect, it, vi } from 'vitest'
import { fetchQARecords, parseQARecord, qaCellValue } from './qaOps'
import { fixtureRecord } from './qaOps.test'
import { qualityFixture, fields } from './qaQuality.fixture'
afterEach(() => vi.unstubAllGlobals())
it('keeps imported historical labels and genuine missing values instead of replacing them with new rule labels', () => {
const raw = {
...fixtureRecord,
record_origin: 'historical_excel',
master_fields: {
question_chinese: '',
coverage: '是',
is_correct: '待确认',
product_category: '原分类',
problem_type: '',
root_cause: '',
language: 'en',
},
}
const item = parseQARecord(raw)
expect(qaCellValue(item, 'coverage')).toBe('是')
expect(qaCellValue(item, 'is_correct')).toBe('待确认')
expect(qaCellValue(item, 'question_chinese')).toBeNull()
expect(qaCellValue(item, 'product_category')).toBe('原分类')
for (const bad of [null, [], { coverage: 123 }, { unapproved: 'x' }])
expect(() => parseQARecord({ ...raw, master_fields: bad })).toThrow('响应无效')
})
it('accepts explicitly versioned master effective fields without inventing a human review or weakening legacy checks', () => {
const quality = {
...qualityFixture,
state: 'unreviewed',
revision: 0,
latest_review: null,
effective: fields,
effective_source: 'master-effective-fields-v1',
}
const row = {
...fixtureRecord,
record_origin: 'historical_excel',
master_fields: { coverage: '是', is_correct: '是', product_category: 'MG400' },
quality,
}
expect(parseQARecord(row).quality?.effective.product_category).toBe('MG400')
expect(parseQARecord(row).quality?.state).toBe('unreviewed')
expect(() => parseQARecord({ ...row, record_origin: undefined })).toThrow()
expect(() => parseQARecord({ ...row, quality: { ...quality, effective_source: undefined } })).toThrow()
const tampered = {
...qualityFixture,
effective_source: 'master-effective-fields-v1',
effective: { ...fields, correctness: 'incorrect' },
}
expect(() => parseQARecord({ ...row, quality: tampered })).toThrow()
})
it('selects the durable master explicitly and leaves original 2.0 callers on their existing dataset', async () => {
const page = { items: [], columns: [], total: 0, has_more: false, next_cursor: '', as_of: '2026-10-19T00:00:00Z' }
const mocked = vi
.fn()
.mockImplementation(() => Promise.resolve(new Response(JSON.stringify({ data: page }), { status: 200 })))
vi.stubGlobal('fetch', mocked)
const query = { start: '2026-10-05T00:00:00Z', end: '2026-10-12T00:00:00Z', keyword: '', cursor: '' }
await fetchQARecords({ ...query, dataset: 'master' } as Parameters<typeof fetchQARecords>[0])
await fetchQARecords(query)
expect(String(mocked.mock.calls[0][0])).toContain('/api/v1/qa-ops/master/records?')
expect(String(mocked.mock.calls[1][0])).toContain('/api/v1/qa-ops/records?')
})