save-review.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { promises as fs } from 'node:fs'
  2. import path from 'node:path'
  3. import { saveReviews } from '../review/index.js'
  4. import { readJsonInput } from '../util/json-input.js'
  5. /**
  6. * save-review <章号> --file=<两审json> [--draft=<repo相对路径>]:两审产物入库。
  7. * JSON:{factCheck|事实审查, editorial|编辑审, mode?, 待确认新专名?, 章摘要?}。
  8. * schema 校验 → 合并 → 落 工作区/审稿.md + 评审报告/(原始输出与归一化分存)。
  9. * 契约:纯返回 {ok, output?, error?}。
  10. */
  11. export async function run(args, options, ctx) {
  12. const chapterNum = parseInt(args[0], 10)
  13. if (isNaN(chapterNum)) return { ok: false, error: '章号必须是数字' }
  14. const spec = await readJsonInput(ctx, options.file, 'file')
  15. if (!spec.ok) return { ok: false, error: spec.error }
  16. const d = spec.data
  17. const rawFact = d.factCheck ?? d.事实审查
  18. const rawEdit = d.editorial ?? d.编辑审
  19. if (!rawFact || !rawEdit) {
  20. return { ok: false, error: 'JSON 需含「factCheck/事实审查」与「editorial/编辑审」两份审稿报告' }
  21. }
  22. const mode = d.mode === 'degraded' ? 'degraded' : 'complete'
  23. const draftRel =
  24. options.draft && options.draft !== true ? options.draft : path.join('工作区', '草稿-A.md')
  25. let draft
  26. try {
  27. // resolve 而非 join:--draft 传绝对路径时 join 会拼出坏路径
  28. draft = await fs.readFile(path.resolve(ctx.repoPath, draftRel), 'utf8')
  29. } catch (err) {
  30. return { ok: false, error: `读不到草稿 ${draftRel}:${err.message}(审稿单要附草稿原文)` }
  31. }
  32. const r = await saveReviews(ctx, {
  33. chapterNum,
  34. rawFact,
  35. rawEdit,
  36. mode,
  37. 待确认新专名: Array.isArray(d.待确认新专名) ? d.待确认新专名 : [],
  38. 章摘要: typeof d.章摘要 === 'string' ? d.章摘要 : '',
  39. draft,
  40. })
  41. if (!r.ok) return { ok: false, error: `两审报告未过 schema 校验:\n- ${r.errors.join('\n- ')}` }
  42. return {
  43. ok: true,
  44. output: `审稿单已落 ${path.join('工作区', '审稿.md')}:共 ${r.merged.issues_count} 个问题,${r.merged.blocking_count} 个阻断${r.merged.has_blocking ? '(有阻断,需处理后再定稿)' : ''}`,
  45. }
  46. }