Files
task-board/migrate.js
T
work-1 0988350e66 修复服务启动问题 + 添加数据库迁移脚本
修复:
- 分离数据库初始化逻辑到独立的 migrate.js
- 避免启动时索引创建顺序问题
- 服务启动不再自动运行 initDatabase

新增:
- migrate.js - 独立的数据库迁移脚本
- 先创建表,再添加外键,最后创建索引

使用方法:
1. 运行迁移: DB_HOST=localhost DB_PORT=5433 DB_NAME=agent_tasks_v2 node migrate.js
2. 启动服务: DB_HOST=localhost DB_PORT=5433 DB_NAME=agent_tasks_v2 node server-v2.js

已测试功能:
 全局规约设置和获取
 项目创建
 项目规约设置
 任务创建
 智能体注册
 任务领取(同时返回全局规约和项目规约)
2026-02-15 21:45:22 +08:00

195 lines
6.1 KiB
JavaScript
Executable File

#!/usr/bin/env node
const { Pool } = require('pg');
const pool = new Pool({
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 5432,
database: process.env.DB_NAME || 'agent_tasks_v2',
user: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'postgres',
});
async function migrate() {
const client = await pool.connect();
try {
console.log('🔧 开始数据库迁移...');
// 创建智能体表
console.log('创建 agents 表...');
await client.query(`
CREATE TABLE IF NOT EXISTS agents (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
type VARCHAR(100),
capabilities JSONB,
status VARCHAR(50) DEFAULT 'idle',
registered_at BIGINT,
last_heartbeat BIGINT
)
`);
// 创建项目表
console.log('创建 projects 表...');
await client.query(`
CREATE TABLE IF NOT EXISTS projects (
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(500) NOT NULL,
description TEXT,
created_by VARCHAR(255),
created_at BIGINT,
updated_at BIGINT,
status VARCHAR(50) DEFAULT 'active'
)
`);
// 创建全局协作规约表
console.log('创建 global_collaboration_rules 表...');
await client.query(`
CREATE TABLE IF NOT EXISTS global_collaboration_rules (
id VARCHAR(255) PRIMARY KEY,
content TEXT NOT NULL,
created_by VARCHAR(255),
created_at BIGINT,
updated_at BIGINT
)
`);
// 创建项目协作规约表
console.log('创建 collaboration_rules 表...');
await client.query(`
CREATE TABLE IF NOT EXISTS collaboration_rules (
id VARCHAR(255) PRIMARY KEY,
project_id VARCHAR(255),
content TEXT NOT NULL,
created_by VARCHAR(255),
created_at BIGINT,
updated_at BIGINT
)
`);
// 创建项目信息共享清单表
console.log('创建 project_notes 表...');
await client.query(`
CREATE TABLE IF NOT EXISTS project_notes (
id VARCHAR(255) PRIMARY KEY,
project_id VARCHAR(255),
content TEXT NOT NULL,
created_by VARCHAR(255),
created_at BIGINT,
updated_at BIGINT
)
`);
// 创建任务表
console.log('创建 tasks 表...');
await client.query(`
CREATE TABLE IF NOT EXISTS tasks (
id VARCHAR(255) PRIMARY KEY,
project_id VARCHAR(255),
parent_task_id VARCHAR(255),
title VARCHAR(500) NOT NULL,
description TEXT,
task_type VARCHAR(50) DEFAULT 'development',
priority VARCHAR(50) DEFAULT 'normal',
status VARCHAR(50) DEFAULT 'initial',
created_by VARCHAR(255),
assigned_to VARCHAR(255),
created_at BIGINT,
updated_at BIGINT,
completed_at BIGINT,
result TEXT
)
`);
// 创建附件表
console.log('创建 attachments 表...');
await client.query(`
CREATE TABLE IF NOT EXISTS attachments (
id VARCHAR(255) PRIMARY KEY,
task_id VARCHAR(255),
filename VARCHAR(500) NOT NULL,
original_name VARCHAR(500) NOT NULL,
file_path VARCHAR(1000) NOT NULL,
file_size BIGINT,
mime_type VARCHAR(100),
uploaded_by VARCHAR(255),
uploaded_at BIGINT
)
`);
// 现在添加外键约束
console.log('添加外键约束...');
await client.query(`
DO $$
BEGIN
-- collaboration_rules 外键
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'collaboration_rules_project_id_fkey'
) THEN
ALTER TABLE collaboration_rules
ADD CONSTRAINT collaboration_rules_project_id_fkey
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
END IF;
-- project_notes 外键
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'project_notes_project_id_fkey'
) THEN
ALTER TABLE project_notes
ADD CONSTRAINT project_notes_project_id_fkey
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
END IF;
-- tasks 外键
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'tasks_project_id_fkey'
) THEN
ALTER TABLE tasks
ADD CONSTRAINT tasks_project_id_fkey
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'tasks_parent_task_id_fkey'
) THEN
ALTER TABLE tasks
ADD CONSTRAINT tasks_parent_task_id_fkey
FOREIGN KEY (parent_task_id) REFERENCES tasks(id) ON DELETE SET NULL;
END IF;
-- attachments 外键
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'attachments_task_id_fkey'
) THEN
ALTER TABLE attachments
ADD CONSTRAINT attachments_task_id_fkey
FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE CASCADE;
END IF;
END $$;
`);
// 创建索引
console.log('创建索引...');
await client.query(`CREATE INDEX IF NOT EXISTS idx_agents_status ON agents(status)`);
await client.query(`CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`);
await client.query(`CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project_id)`);
await client.query(`CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_task_id)`);
await client.query(`CREATE INDEX IF NOT EXISTS idx_tasks_assigned ON tasks(assigned_to)`);
await client.query(`CREATE INDEX IF NOT EXISTS idx_attachments_task ON attachments(task_id)`);
await client.query(`CREATE INDEX IF NOT EXISTS idx_project_notes_project ON project_notes(project_id)`);
console.log('✅ 数据库迁移完成!');
} catch (err) {
console.error('❌ 迁移失败:', err);
process.exit(1);
} finally {
client.release();
await pool.end();
}
}
migrate();