/** * 清运行数据 —— 开发期反复用:把跑过的单清空,配置原样留着。 * * pnpm --filter @app/api reset-runs * * **清的是「跑出来的」**:任务、工作流、卡、任务记忆、事件、监听、台账行、活动记忆… * **留的是「配置好的」**:员工与岗位授权、会话、工作组、流程包、活动库、工具、 * 触发器、通道、模型实例、纪要。 * * 直接走 SQL 而不绕模块:模块出口里没有、也不该有「删掉所有运行痕迹」这种动作 —— * 留痕只增不改是系统的规矩,清库是**开发期的外科手术**,不是系统的一项能力。 */ import { Pool } from 'pg'; import { loadConfig } from './config.ts'; /** 顺序无所谓:一条 TRUNCATE 里的表会一起截断,外键互指也不冲突 */ const RUN_TABLES = [ 'sys.task', 'sys.task_memory', 'sys.task_memory_seal', 'sys.task_view', 'sys.work_order', 'sys.chat_card', 'sys.chat_message', 'sys.system_message', 'sys.node_instance', 'sys.workflow', 'sys.flow_state', 'sys.loop_state', 'sys.listener', 'sys.action_intent', 'sys.event', 'sys.event_delivery', 'sys.event_consumption', 'sys.outbound_mail', 'sys.outbound_ref', 'sys.trigger_claim', 'sys.report', 'sys.replay_model', 'sys.replay_tool', /* 活动记忆是跑出来的蒸馏物,跟着运行数据一起清 */ 'sys.activity_memory', 'sys.asset_increment', /* 纪要是人记的,但开发期同属「跑出来的东西」—— 清库要清得干净,不留半场旧会 */ 'sys.minute', 'sys.minute_resolution', ]; export async function resetRuns(): Promise { const pool = new Pool({ connectionString: loadConfig().databaseUrl, max: 2 }); try { // 台账的业务表是动态建的,名字问库不写死 const ledger = await pool.query<{ name: string }>( `select quote_ident(schemaname) || '.' || quote_ident(tablename) as name from pg_tables where schemaname = 'ledger'`, ); const all = [...RUN_TABLES, ...ledger.rows.map((r) => r.name)]; await pool.query(`truncate table ${all.join(', ')} restart identity cascade`); process.stdout.write(`已清运行数据:${all.length} 张表(配置与组织数据原样保留)\n`); } finally { await pool.end(); } } if (import.meta.url === `file://${process.argv[1]}`) { await resetRuns(); process.exit(0); }