#!/usr/bin/env node /** * backfill-ceo-hire.js —— 存量公司补雇 ceo * * 依据: docs/todo/system-design/39-boss-agent-task-supervision.md §二 P1「缺口 B」 * * `ceo` 不在任何 org-graph-template 里,也没有自动招聘钩子——POST /api/company/create * 这次起改成新建公司时固定雇一次,但存量公司不会补跑那条创建流程,需要这个脚本单独补雇。 * * 幂等: hire() 本身按 company_agents 表判重(见 company-service.js:429),已经雇过的公司 * 会拿到 status='already_exists',跳过不算失败,可重复执行。 * * 用法: * node scripts/backfill-ceo-hire.js */ const fs = require('fs'); const path = require('path'); const DATA_DIR = path.resolve(__dirname, '../data/companies'); function main() { const { CompanyService } = require('../server/services/company-service'); const companyService = new CompanyService(); if (!fs.existsSync(DATA_DIR)) { console.log('[backfill-ceo-hire] data/companies/ 不存在,无需处理'); return; } const dirs = fs.readdirSync(DATA_DIR, { withFileTypes: true }).filter((d) => d.isDirectory()); let hired = 0; let skipped = 0; let failed = 0; for (const d of dirs) { const fp = path.join(DATA_DIR, d.name, 'company.json'); if (!fs.existsSync(fp)) continue; try { const result = companyService.hire(d.name, 'ceo', {}); if (result.status === 'already_exists') { skipped += 1; } else { console.log(`[backfill-ceo-hire] ${d.name} → ceo(${result.status})`); hired += 1; } } catch (e) { console.error(`[backfill-ceo-hire] ${d.name} 雇 ceo 失败: ${e.message}`); failed += 1; } } console.log(`[backfill-ceo-hire] 完成:新雇 ${hired} 家,跳过(已雇过)${skipped} 家,失败 ${failed} 家`); if (failed > 0) process.exitCode = 1; } main();