2026-02-15 13:41:49 +08:00
const express = require ( 'express' );
const sqlite3 = require ( 'sqlite3' ). verbose ();
const path = require ( 'path' );
const app = express ();
2026-02-24 15:04:25 +08:00
const PORT = 3000 ;
2026-02-15 13:41:49 +08:00
// 中间件
2026-02-24 15:04:25 +08:00
app . use ( express . json ());
2026-02-15 13:41:49 +08:00
app . use ( express . static ( 'public' ));
2026-02-24 15:04:25 +08:00
// 数据库连接
const db = new sqlite3 . Database ( './tasks.db' , ( err ) => {
2026-02-15 13:41:49 +08:00
if ( err ) {
2026-02-24 15:04:25 +08:00
console . error ( '❌ 数据库连接失败:' , err . message );
process . exit ( 1 );
2026-02-15 13:41:49 +08:00
}
2026-02-24 15:04:25 +08:00
console . log ( '✅ 已连接到 SQLite 数据库' );
2026-02-15 13:41:49 +08:00
});
2026-02-24 15:04:25 +08:00
// 初始化数据库表
db . serialize (() => {
// 项目表
db . run ( `CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'active',
created_by TEXT DEFAULT 'human',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)` );
// 任务表
db . run ( `CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL,
parent_id INTEGER,
title TEXT NOT NULL,
description TEXT,
type TEXT DEFAULT 'development',
priority TEXT DEFAULT 'normal',
status TEXT DEFAULT 'initial',
assigned_to TEXT,
created_by TEXT DEFAULT 'human',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id),
FOREIGN KEY (parent_id) REFERENCES tasks(id)
)` );
// 智能体表
db . run ( `CREATE TABLE IF NOT EXISTS agents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL,
type TEXT,
capabilities TEXT,
status TEXT DEFAULT 'idle',
current_task TEXT,
completed_tasks INTEGER DEFAULT 0,
last_heartbeat DATETIME DEFAULT CURRENT_TIMESTAMP
)` );
// 附件表
db . run ( `CREATE TABLE IF NOT EXISTS attachments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id INTEGER NOT NULL,
filename TEXT NOT NULL,
filepath TEXT NOT NULL,
size INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (task_id) REFERENCES tasks(id)
)` );
// 规约表 (支持全局和项目级别)
db . run ( `CREATE TABLE IF NOT EXISTS rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER,
rule_no TEXT NOT NULL,
rule_type TEXT NOT NULL,
description TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (project_id) REFERENCES projects(id)
)` );
console . log ( '✅ 数据库表已初始化' );
});
2026-02-15 13:41:49 +08:00
// ==================== API 路由 ====================
2026-02-24 16:42:52 +08:00
// 健康检查
app . get ( '/health' , ( req , res ) => {
res . json ({
status : 'ok' ,
timestamp : new Date (). toISOString (),
uptime : process . uptime (),
memory : process . memoryUsage (),
version : require ( './package.json' ). version
});
});
2026-02-24 15:04:25 +08:00
// 统计信息
2026-02-15 13:41:49 +08:00
app . get ( '/api/stats' , ( req , res ) => {
2026-02-24 15:04:25 +08:00
const stats = {};
2026-02-15 13:41:49 +08:00
2026-02-24 15:04:25 +08:00
db . get ( 'SELECT COUNT(*) as count FROM projects' , ( err , row ) => {
stats . projects = row ? row . count : 0 ;
2026-02-15 13:41:49 +08:00
2026-02-24 15:04:25 +08:00
db . get ( 'SELECT COUNT(*) as count FROM tasks' , ( err , row ) => {
stats . tasks = row ? row . count : 0 ;
2026-02-15 13:41:49 +08:00
2026-02-24 15:04:25 +08:00
db . get ( 'SELECT COUNT(*) as count FROM tasks WHERE status = "in_progress"' , ( err , row ) => {
stats . in_progress_tasks = row ? row . count : 0 ;
2026-02-15 13:41:49 +08:00
2026-02-24 15:04:25 +08:00
db . get ( 'SELECT COUNT(*) as count FROM tasks WHERE status = "completed"' , ( err , row ) => {
stats . completed_tasks = row ? row . count : 0 ;
2026-02-15 13:41:49 +08:00
2026-02-24 15:04:25 +08:00
db . get ( 'SELECT COUNT(*) as count FROM agents' , ( err , row ) => {
stats . total_agents = row ? row . count : 0 ;
2026-02-15 13:41:49 +08:00
2026-02-24 15:04:25 +08:00
db . get ( 'SELECT COUNT(*) as count FROM agents WHERE status = "busy"' , ( err , row ) => {
stats . active_agents = row ? row . count : 0 ;
2026-02-15 13:41:49 +08:00
res . json ( stats );
});
});
});
});
});
});
});
2026-02-24 15:04:25 +08:00
// 项目管理
app . get ( '/api/projects' , ( req , res ) => {
db . all ( 'SELECT * FROM projects ORDER BY created_at DESC' , ( err , rows ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ( rows || []);
});
});
app . post ( '/api/projects' , ( req , res ) => {
const { name , description , created_by = 'human' } = req . body ;
db . run (
'INSERT INTO projects (name, description, created_by) VALUES (?, ?, ?)' ,
[ name , description , created_by ],
function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ({ id : this . lastID , name , description , created_by });
}
);
});
app . get ( '/api/projects/:id' , ( req , res ) => {
db . get ( 'SELECT * FROM projects WHERE id = ?' , [ req . params . id ], ( err , row ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
if ( ! row ) return res . status ( 404 ). json ({ error : 'Project not found' });
res . json ( row );
});
});
app . delete ( '/api/projects/:id' , ( req , res ) => {
// 先删除项目下的所有任务
db . run ( 'DELETE FROM tasks WHERE project_id = ?' , [ req . params . id ], ( err ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
// 然后删除项目
db . run ( 'DELETE FROM projects WHERE id = ?' , [ req . params . id ], function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
if ( this . changes === 0 ) return res . status ( 404 ). json ({ error : 'Project not found' });
res . json ({ success : true });
});
});
});
// 任务管理
app . get ( '/api/tasks' , ( req , res ) => {
const { project_id } = req . query ;
let query = 'SELECT t.*, (SELECT COUNT(*) FROM tasks WHERE parent_id = t.id) as subtask_count, (SELECT COUNT(*) FROM attachments WHERE task_id = t.id) as attachment_count FROM tasks t' ;
let params = [];
if ( project_id ) {
query += ' WHERE t.project_id = ?' ;
params . push ( project_id );
}
query += ' ORDER BY t.created_at DESC' ;
db . all ( query , params , ( err , rows ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ( rows || []);
});
});
app . post ( '/api/tasks' , ( req , res ) => {
const { project_id , parent_id , title , description , type = 'development' , priority = 'normal' , status = 'initial' , assigned_to , created_by = 'human' } = req . body ;
db . run (
'INSERT INTO tasks (project_id, parent_id, title, description, type, priority, status, assigned_to, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)' ,
[ project_id , parent_id || null , title , description , type , priority , status , assigned_to || null , created_by ],
function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ({ id : this . lastID , project_id , title , type , priority , status });
}
);
});
app . get ( '/api/tasks/:id' , ( req , res ) => {
db . get ( 'SELECT * FROM tasks WHERE id = ?' , [ req . params . id ], ( err , task ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
if ( ! task ) return res . status ( 404 ). json ({ error : 'Task not found' });
// 获取附件
db . all ( 'SELECT * FROM attachments WHERE task_id = ?' , [ req . params . id ], ( err , attachments ) => {
task . attachments = attachments || [];
// 获取子任务
db . all ( 'SELECT * FROM tasks WHERE parent_id = ?' , [ req . params . id ], ( err , subtasks ) => {
task . subtasks = subtasks || [];
res . json ( task );
});
});
});
});
app . put ( '/api/tasks/:id' , ( req , res ) => {
const updates = [];
const values = [];
[ 'status' , 'type' , 'priority' , 'assigned_to' , 'title' , 'description' ]. forEach ( field => {
if ( req . body [ field ] !== undefined ) {
updates . push ( ` ${ field } = ?` );
values . push ( req . body [ field ]);
}
});
if ( updates . length === 0 ) {
return res . status ( 400 ). json ({ error : 'No fields to update' });
}
values . push ( req . params . id );
db . run (
`UPDATE tasks SET ${ updates . join ( ', ' ) } WHERE id = ?` ,
values ,
function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
if ( this . changes === 0 ) return res . status ( 404 ). json ({ error : 'Task not found' });
res . json ({ success : true });
}
);
});
app . delete ( '/api/tasks/:id' , ( req , res ) => {
db . run ( 'DELETE FROM tasks WHERE id = ?' , [ req . params . id ], function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ({ success : true });
});
});
// 智能体管理
app . get ( '/api/agents' , ( req , res ) => {
db . all ( 'SELECT * FROM agents ORDER BY name' , ( err , rows ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ( rows || []);
});
});
app . post ( '/api/agents' , ( req , res ) => {
const { name , type , capabilities } = req . body ;
db . run (
'INSERT INTO agents (name, type, capabilities) VALUES (?, ?, ?)' ,
[ name , type , JSON . stringify ( capabilities )],
function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ({ id : this . lastID , name , type , capabilities });
}
);
});
// 规约管理 (支持多条目)
// 获取全局规约列表
app . get ( '/api/rules/global' , ( req , res ) => {
db . all ( 'SELECT * FROM rules WHERE project_id IS NULL ORDER BY rule_no' , ( err , rows ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ( rows || []);
});
});
// 获取项目规约列表
app . get ( '/api/rules/project/:projectId' , ( req , res ) => {
db . all ( 'SELECT * FROM rules WHERE project_id = ? ORDER BY rule_no' , [ req . params . projectId ], ( err , rows ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ( rows || []);
});
});
// 获取单个规约
app . get ( '/api/rules/:id' , ( req , res ) => {
db . get ( 'SELECT * FROM rules WHERE id = ?' , [ req . params . id ], ( err , row ) => {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
if ( ! row ) return res . status ( 404 ). json ({ error : 'Rule not found' });
res . json ( row );
});
});
// 创建规约
app . post ( '/api/rules' , ( req , res ) => {
const { project_id , rule_no , rule_type , description } = req . body ;
db . run (
'INSERT INTO rules (project_id, rule_no, rule_type, description) VALUES (?, ?, ?, ?)' ,
[ project_id || null , rule_no , rule_type , description ],
function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ({ id : this . lastID , project_id , rule_no , rule_type , description });
}
);
});
// 更新规约
app . put ( '/api/rules/:id' , ( req , res ) => {
const { rule_no , rule_type , description } = req . body ;
const updates = [];
const values = [];
if ( rule_no !== undefined ) { updates . push ( 'rule_no = ?' ); values . push ( rule_no ); }
if ( rule_type !== undefined ) { updates . push ( 'rule_type = ?' ); values . push ( rule_type ); }
if ( description !== undefined ) { updates . push ( 'description = ?' ); values . push ( description ); }
updates . push ( 'updated_at = CURRENT_TIMESTAMP' );
if ( values . length === 0 ) {
return res . status ( 400 ). json ({ error : 'No fields to update' });
}
values . push ( req . params . id );
db . run (
`UPDATE rules SET ${ updates . join ( ', ' ) } WHERE id = ?` ,
values ,
function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ({ success : true });
}
);
});
// 删除规约
app . delete ( '/api/rules/:id' , ( req , res ) => {
db . run ( 'DELETE FROM rules WHERE id = ?' , [ req . params . id ], function ( err ) {
if ( err ) return res . status ( 500 ). json ({ error : err . message });
res . json ({ success : true });
});
});
2026-02-24 16:42:52 +08:00
// 错误处理中间件(必须在所有路由之后)
app . use (( err , req , res , next ) => {
console . error ( '❌ API错误:' , err . stack );
res . status ( 500 ). json ({
error : err . message || '服务器内部错误' ,
timestamp : new Date (). toISOString ()
});
});
2026-02-15 13:41:49 +08:00
// 启动服务器
2026-02-24 16:42:52 +08:00
const server = app . listen ( PORT , () => {
2026-02-24 15:04:25 +08:00
console . log ( `🚀 多智能体任务管理系统已启动` );
console . log ( ` 本地访问: http://localhost: ${ PORT } ` );
console . log ( ` 远程访问: http://10.0.6.5: ${ PORT } ` );
2026-02-15 13:41:49 +08:00
});
2026-02-24 16:42:52 +08:00
// 监听端口错误
server . on ( 'error' , ( err ) => {
if ( err . code === 'EADDRINUSE' ) {
console . error ( `❌ 端口 ${ PORT } 已被占用` );
console . error ( ` 请先停止占用端口的进程: lsof -ti: ${ PORT } | xargs kill -9` );
process . exit ( 1 );
} else {
console . error ( '❌ 服务器启动失败:' , err );
process . exit ( 1 );
}
});
// 全局异常捕获
process . on ( 'uncaughtException' , ( err ) => {
console . error ( '❌ 未捕获异常:' , err );
console . error ( ' 堆栈:' , err . stack );
// 不退出进程,继续运行
});
process . on ( 'unhandledRejection' , ( reason , promise ) => {
console . error ( '❌ 未处理的Promise拒绝:' , reason );
console . error ( ' Promise:' , promise );
// 不退出进程,继续运行
});
2026-02-15 13:41:49 +08:00
// 优雅关闭
process . on ( 'SIGINT' , () => {
2026-02-24 16:42:52 +08:00
console . log ( '\n⏸️ 收到关闭信号,准备关闭服务器...' );
server . close (() => {
console . log ( '📡 HTTP服务器已关闭' );
db . close (( err ) => {
if ( err ) {
console . error ( '❌ 数据库关闭失败:' , err );
process . exit ( 1 );
}
console . log ( '💾 数据库连接已关闭' );
console . log ( '👋 服务器已完全关闭' );
process . exit ( 0 );
});
2026-02-15 13:41:49 +08:00
});
2026-02-24 16:42:52 +08:00
// 强制超时退出(10秒)
setTimeout (() => {
console . error ( '⚠️ 强制退出(超时)' );
process . exit ( 1 );
}, 10000 );
2026-02-15 13:41:49 +08:00
});