From 0988350e66fe405d641508a80af357dd979f862f Mon Sep 17 00:00:00 2001 From: work-1 Date: Sun, 15 Feb 2026 21:45:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=8D=E5=8A=A1=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E9=97=AE=E9=A2=98=20+=20=E6=B7=BB=E5=8A=A0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E8=BF=81=E7=A7=BB=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复: - 分离数据库初始化逻辑到独立的 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 已测试功能: ✅ 全局规约设置和获取 ✅ 项目创建 ✅ 项目规约设置 ✅ 任务创建 ✅ 智能体注册 ✅ 任务领取(同时返回全局规约和项目规约) --- migrate.js | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++ server-v2.js | 3 +- 2 files changed, 196 insertions(+), 1 deletion(-) create mode 100755 migrate.js diff --git a/migrate.js b/migrate.js new file mode 100755 index 0000000..721ecbd --- /dev/null +++ b/migrate.js @@ -0,0 +1,194 @@ +#!/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(); diff --git a/server-v2.js b/server-v2.js index c0761dc..d9ad7d7 100644 --- a/server-v2.js +++ b/server-v2.js @@ -57,7 +57,8 @@ pool.connect((err, client, release) => { } else { console.log('✅ 已连接到 PostgreSQL 数据库'); release(); - initDatabase(); + // 数据库表已通过 migrate.js 初始化 + console.log('💡 提示: 如需初始化数据库,请运行: node migrate.js'); } });