/** * 数字口径机械防线(2026-09-19 critique P0 → 结构强制收尾): * 1) 「目标口径,非既成结果」必须来自 METRICS_BASIS_NOTE 单一真源,不得散写字面量; * 2) 每个呈现结果型数字的渲染源(含详情页共享数字组件)必须接入 MetricsBasisNote; * 3) 走共享数字样式渲染的指标必须声明 basis(target|team-history|verified), * 且口径解析对缺失/非法值保守回落到最弱的 target; * 4) 禁止再引入「数字源自真实客户案例 / 经过实战验证」式虚构佐证(本站零公开客户案例)。 * 扫描范围:src/app + src/components 的 .ts/.tsx(排除测试文件与 _archive 归档)。 */ import { readdirSync, readFileSync, statSync } from 'fs'; import { join } from 'path'; import { METRICS_BASIS_NOTE, METRIC_BASES, METRIC_BASIS_NOTES, FORBIDDEN_PROOF_PHRASES, resolveMetricBasis, weakestBasis, } from './metrics-basis'; import { PRODUCTS } from './products'; import { SOLUTIONS } from './solutions'; import { STANDALONE_PRODUCTS } from '../../../prisma/seeds/standalone-products'; const SOURCE_ROOTS = ['src/app', 'src/components']; /** 呈现结果型数字、必须接入口径角注的页面/组件源文件。 */ const REQUIRED_ANNOTATED_SOURCES = [ 'src/app/(marketing)/products/products-content-v3.tsx', 'src/app/(marketing)/solutions/solutions-content-v3.tsx', 'src/app/(marketing)/services/services-content-v3.tsx', 'src/app/(marketing)/home-content-v15.tsx', // 详情页同样以大数字样式渲染 dataProofs,不得裸奔 'src/components/content/sections.tsx', 'src/components/detail/detail-trust-section.tsx', 'src/components/detail/detail-product-value.tsx', ]; function collectSourceFiles(dir: string, acc: string[] = []): string[] { for (const entry of readdirSync(dir)) { const full = join(dir, entry); if (entry === '_archive') continue; const stat = statSync(full); if (stat.isDirectory()) { collectSourceFiles(full, acc); } else if (/\.(ts|tsx)$/.test(entry) && !/\.test\.tsx?$/.test(entry)) { acc.push(full); } } return acc; } /** 把三处 seed 里的全部数字条目摊平,用于口径声明完整性断言。 */ function allSeedMetricBases(): Array { const bases: Array = []; for (const p of [...PRODUCTS, ...STANDALONE_PRODUCTS]) { (p.metrics ?? []).forEach((m) => bases.push(m.basis)); (p.dataProofs ?? []).forEach((d) => bases.push(d.basis)); } for (const s of SOLUTIONS) { (s.outcomes ?? []).forEach((o) => bases.push(o.basis)); (s.dataProofs ?? []).forEach((d) => bases.push(d.basis)); } return bases; } describe('结果型数字口径角注防线', () => { it('METRICS_BASIS_NOTE 固定为「目标口径,非既成结果」', () => { expect(METRICS_BASIS_NOTE).toBe('目标口径,非既成结果'); }); it('METRICS_BASIS_NOTE 等于最弱口径 target 的文案', () => { expect(METRICS_BASIS_NOTE).toBe(METRIC_BASIS_NOTES.target); }); it('生产源码不得硬编码口径角注字面量(必须引用单一真源)', () => { const violations: string[] = []; for (const root of SOURCE_ROOTS) { for (const file of collectSourceFiles(root)) { if (file.endsWith('lib/constants/metrics-basis.ts')) continue; const lines = readFileSync(file, 'utf-8').split('\n'); lines.forEach((line, i) => { if (line.includes(METRICS_BASIS_NOTE)) { violations.push(`${file}:${i + 1}`); } }); } } expect(violations).toEqual([]); }); it('结果型数字页面均接入 MetricsBasisNote', () => { for (const file of REQUIRED_ANNOTATED_SOURCES) { const src = readFileSync(file, 'utf-8'); expect({ file, used: src.includes(' { it('枚举固定为 target / team-history / verified', () => { expect(METRIC_BASES).toEqual(['target', 'team-history', 'verified']); }); it('三个口径均有文案,无空串', () => { for (const basis of METRIC_BASES) { expect(METRIC_BASIS_NOTES[basis].length).toBeGreaterThan(0); } }); it('合法口径原样解析(正控制,防匹配零的假绿)', () => { expect(resolveMetricBasis('verified')).toBe('verified'); expect(resolveMetricBasis('team-history')).toBe('team-history'); expect(resolveMetricBasis('target')).toBe('target'); }); it('缺失/非法/大小写错误一律保守回落到 target', () => { expect(resolveMetricBasis(undefined)).toBe('target'); expect(resolveMetricBasis(null)).toBe('target'); expect(resolveMetricBasis('VERIFIED')).toBe('target'); expect(resolveMetricBasis('已验证')).toBe('target'); expect(resolveMetricBasis('verified ')).toBe('target'); }); it('weakestBasis 取最弱口径:任一 target 存在即整体为 target', () => { expect(weakestBasis(['verified', 'team-history'])).toBe('team-history'); expect(weakestBasis(['verified', 'target'])).toBe('target'); expect(weakestBasis(['verified', 'verified'])).toBe('verified'); }); it('weakestBasis 空数组与含未声明项均落到 target', () => { expect(weakestBasis([])).toBe('target'); expect(weakestBasis(['verified', undefined])).toBe('target'); }); }); describe('seed 数字必须显式声明口径', () => { it('存在可检出的数字条目(覆盖证明,防空跑)', () => { expect(allSeedMetricBases().length).toBeGreaterThan(40); }); it('每条 metrics / outcomes / dataProofs 均声明 basis', () => { const missing = allSeedMetricBases().filter((b) => !b); expect(missing).toEqual([]); }); it('声明的 basis 全部合法', () => { const invalid = allSeedMetricBases().filter( (b) => !(METRIC_BASES as readonly string[]).includes(String(b)), ); expect(invalid).toEqual([]); }); it('当前无任何条目自称 verified(零编造:尚无客户实测数据)', () => { const claimed = allSeedMetricBases().filter((b) => b === 'verified'); expect(claimed).toEqual([]); }); }); describe('虚构佐证禁词防线', () => { it('正控制:禁词表非空且每条均可被检出', () => { expect(FORBIDDEN_PROOF_PHRASES.length).toBeGreaterThan(0); for (const phrase of FORBIDDEN_PROOF_PHRASES) { expect(`示例文案${phrase}结尾`).toContain(phrase); } }); it('生产源码不含「真实客户案例 / 实战验证」式虚构佐证', () => { const violations: string[] = []; for (const root of SOURCE_ROOTS) { for (const file of collectSourceFiles(root)) { const lines = readFileSync(file, 'utf-8').split('\n'); lines.forEach((line, i) => { const hit = FORBIDDEN_PROOF_PHRASES.find((p) => line.includes(p)); if (hit) violations.push(`${file}:${i + 1} ${hit}`); }); } } expect(violations).toEqual([]); }); });