create-data-intake-pack-smoke.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #!/usr/bin/env node
  2. const fs = require('fs');
  3. const os = require('os');
  4. const path = require('path');
  5. const { spawnSync } = require('child_process');
  6. const { HISTORY_HEADER, REVIEW_HEADER } = require('./create-data-intake-pack');
  7. const root = path.resolve(__dirname, '..');
  8. function main() {
  9. const output = fs.mkdtempSync(path.join(os.tmpdir(), 'tihao-data-intake-'));
  10. const result = spawnSync(process.execPath, [
  11. path.join(root, 'scripts', 'create-data-intake-pack.js'),
  12. '--output',
  13. output
  14. ], { cwd: root, encoding: 'utf8' });
  15. if (result.status !== 0) {
  16. process.stderr.write(result.stderr || result.stdout || '');
  17. throw new Error('create-data-intake-pack failed');
  18. }
  19. const historyCsv = path.join(output, 'history-data-template.csv');
  20. const reviewCsv = path.join(output, 'manual-review-template.csv');
  21. const readme = path.join(output, 'README.md');
  22. assert(fs.existsSync(historyCsv), 'history template should exist');
  23. assert(fs.existsSync(reviewCsv), 'review template should exist');
  24. assert(fs.existsSync(readme), 'README should exist');
  25. assert(readHeader(historyCsv) === HISTORY_HEADER.join(','), 'history template header should match history:from-csv fields');
  26. assert(readHeader(reviewCsv) === REVIEW_HEADER.join(','), 'review template header should match review/customer-effect fields');
  27. const allText = [historyCsv, reviewCsv, readme].map(file => fs.readFileSync(file, 'utf8')).join('\n');
  28. assert(!/(sk-[A-Za-z0-9_-]{20,}|r:[A-Za-z0-9]{20,}|Authorization\s*[:=]\s*Bearer)/i.test(allText), 'data intake pack should not contain secrets');
  29. assert(allText.includes('客户选择'), 'templates should include customer decision field');
  30. assert(allText.includes('历史人工补号量基线'), 'templates should include historical manual supplement baseline');
  31. assert(allText.includes('本轮人工补号量'), 'templates should include current manual supplement count');
  32. assert(allText.includes('字段填写验收表'), 'README should include field checklist');
  33. assert(allText.includes('常见退回原因'), 'README should explain common rejection reasons');
  34. assert(allText.includes('npm run intake:readiness'), 'README should tell business to run intake readiness first');
  35. assert(allText.includes('客户拒绝样本必须填写'), 'README should explain rejection reason requirement');
  36. assert(fs.readFileSync(readme, 'utf8').includes('才能宣称客户效果证明完成'), 'README should preserve proof boundary');
  37. console.log(JSON.stringify({ ok: true, output, files: 3 }, null, 2));
  38. }
  39. function readHeader(file) {
  40. return fs.readFileSync(file, 'utf8').replace(/^\uFEFF/, '').split(/\r?\n/)[0];
  41. }
  42. function assert(condition, message) {
  43. if (!condition) throw new Error(message);
  44. }
  45. main();