| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- #!/usr/bin/env node
- const {
- getPlatformRules,
- classifyTier,
- evaluateCreatorDataQuality
- } = require('../mcp/src/features/tihao-sourcing/platform-quality-rules');
- function main() {
- // 规则库应覆盖技能包支持的平台
- assert(getPlatformRules('xiaohongshu').tiers.length >= 4, '小红书应有完整达人分级');
- assert(getPlatformRules('douyin').tiers.length >= 5, '抖音应有完整达人分级');
- assert(Object.keys(getPlatformRules('xiaohongshu').metrics).length >= 5, '小红书应结构化互动率/赞藏比/评分/垂直度/商业占比阈值');
- // 达人分级
- assert(classifyTier('xiaohongshu', 180000).name === '腰部KOL', '小红书 18w 应为腰部KOL');
- assert(classifyTier('xiaohongshu', 3000).name === '素人', '小红书 3000 应为素人');
- assert(classifyTier('douyin', 3000000).name === '腰部KOL', '抖音 300w 应为腰部KOL');
- assert(classifyTier('douyin', 20000000).name === '超头部KOL', '抖音 2000w 应为超头部KOL');
- // 成功样本:小红书 18w 粉,粉丝量达标,缺失指标不误扣
- const xhs = evaluateCreatorDataQuality({ platform: 'xiaohongshu', fansCount: 180000 });
- assert(xhs.tier === '腰部KOL', '成功样本层级正确');
- assert(xhs.score >= 50, '粉丝量达标但缺互动率等指标时不应误扣到不及格');
- assert(xhs.missingMetrics.includes('赞藏比(收藏/点赞)'), '未采集的赞藏比应标待补证');
- // 翻车样本:抖音 500w 粉但互动率虚胖 + 负增长 + 低活跃
- const dy = evaluateCreatorDataQuality({ platform: 'douyin', fansCount: 5000000, interactionRate: 0.8, fanGrowthRate30d: -5, lowActivity: true });
- assert(dy.tier === '头部KOL', '翻车样本粉丝层级仍按粉丝量分类');
- assert(dy.riskCount >= 3, '翻车样本应命中互动率/负增长/低活跃多个危险信号');
- assert(dy.score < 30, '多个危险信号应显著压低数据质量分');
- // 阈值方向:商业占比是 max 方向(越高越危险)
- const commercial = evaluateCreatorDataQuality({ platform: 'douyin', fansCount: 500000, commercialRatio: 60 });
- const commercialCheck = commercial.checks.find(item => item.label === '商业内容占比');
- assert(commercialCheck && commercialCheck.verdict === 'risk', '商业占比 60% 应判定为危险');
- console.log(JSON.stringify({
- ok: true,
- xhsScore: xhs.score,
- douyinRiskCount: dy.riskCount,
- douyinScore: dy.score
- }, null, 2));
- }
- function assert(condition, message) {
- if (!condition) throw new Error(message);
- }
- if (require.main === module) main();
|