forked from ChaiHao/BPOS-MVP
用户纠正:我在验证测试台时把节点指派给了他本人(Chaihao),七条测试单堆进了 他的工作台 —— 而我自己就有 AI 测试账号。真实员工的工作台是他干活的地方, 不是试验场;混进去的测试单还要他自己分辨、自己清。 - 清掉全部运行数据(reset-runs:50 张表,配置与组织原样保留)—— 柴浩名下任务 0、工单 0;流程包/员工/活动配置一条没动 - **reset-runs 补上 sys.trace_span**:span 是运行痕,与工作流同生共死; 漏清它,清完运行数据后观测面还挂着 62 条孤儿 span(实测) - 规矩记进记忆:试跑指派一律给 AI 账号,测完主动清运行数据 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
/**
|
|
* 清运行数据 —— 开发期反复用:把跑过的单清空,配置原样留着。
|
|
*
|
|
* 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',
|
|
// 全链 Trace:span 是运行痕,与工作流同生共死 —— 清运行数据不清它,观测面会挂着一堆孤儿
|
|
'sys.trace_span',
|
|
'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<void> {
|
|
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);
|
|
}
|