agentdev-webui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/agent-api.js +530 -0
- package/lib/auth.js +127 -0
- package/lib/config.js +53 -0
- package/lib/database.js +762 -0
- package/lib/device-flow.js +257 -0
- package/lib/email.js +420 -0
- package/lib/encryption.js +112 -0
- package/lib/github.js +339 -0
- package/lib/history.js +143 -0
- package/lib/pwa.js +107 -0
- package/lib/redis-logs.js +226 -0
- package/lib/routes.js +680 -0
- package/migrations/000_create_database.sql +33 -0
- package/migrations/001_create_agentdev_schema.sql +135 -0
- package/migrations/001_create_agentdev_schema.sql.old +100 -0
- package/migrations/001_create_agentdev_schema_fixed.sql +135 -0
- package/migrations/002_add_github_token.sql +17 -0
- package/migrations/003_add_agent_logs_table.sql +23 -0
- package/migrations/004_remove_oauth_columns.sql +11 -0
- package/migrations/005_add_projects.sql +44 -0
- package/migrations/006_project_github_token.sql +7 -0
- package/migrations/007_project_repositories.sql +12 -0
- package/migrations/008_add_notifications.sql +20 -0
- package/migrations/009_unified_oauth.sql +153 -0
- package/migrations/README.md +97 -0
- package/package.json +37 -0
- package/public/css/styles.css +1140 -0
- package/public/device.html +384 -0
- package/public/docs.html +862 -0
- package/public/docs.md +697 -0
- package/public/favicon.svg +5 -0
- package/public/index.html +271 -0
- package/public/js/app.js +2379 -0
- package/public/login.html +224 -0
- package/public/profile.html +394 -0
- package/public/register.html +392 -0
- package/public/reset-password.html +349 -0
- package/public/verify-email.html +177 -0
- package/server.js +1450 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-- Create separate AgentDev database
|
|
2
|
+
-- Run with: psql -h localhost -p 6432 -U postgres -f migrations/000_create_database.sql
|
|
3
|
+
|
|
4
|
+
-- Create database
|
|
5
|
+
CREATE DATABASE agentdev OWNER postgres;
|
|
6
|
+
|
|
7
|
+
-- Create dedicated user
|
|
8
|
+
CREATE USER agentdev WITH PASSWORD 'agentdev_secure_password_change_me';
|
|
9
|
+
|
|
10
|
+
-- Grant privileges
|
|
11
|
+
GRANT CONNECT ON DATABASE agentdev TO agentdev;
|
|
12
|
+
GRANT ALL PRIVILEGES ON DATABASE agentdev TO agentdev;
|
|
13
|
+
|
|
14
|
+
\c agentdev
|
|
15
|
+
|
|
16
|
+
-- Grant schema privileges
|
|
17
|
+
GRANT ALL PRIVILEGES ON SCHEMA public TO agentdev;
|
|
18
|
+
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO agentdev;
|
|
19
|
+
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO agentdev;
|
|
20
|
+
|
|
21
|
+
-- Set default privileges for future tables
|
|
22
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO agentdev;
|
|
23
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO agentdev;
|
|
24
|
+
|
|
25
|
+
-- Create uuid extension (useful for future)
|
|
26
|
+
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
27
|
+
|
|
28
|
+
-- Success message
|
|
29
|
+
\echo '✓ Database agentdev created successfully'
|
|
30
|
+
\echo '✓ User agentdev created with full privileges'
|
|
31
|
+
\echo ''
|
|
32
|
+
\echo 'Next step: Run migrations/001_create_agentdev_schema.sql'
|
|
33
|
+
\echo ' psql -h localhost -p 6432 -U agentdev -d agentdev -f migrations/001_create_agentdev_schema.sql'
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
-- AgentDev Distributed System Database Schema
|
|
2
|
+
-- Fixed version without circular foreign key dependencies
|
|
3
|
+
|
|
4
|
+
BEGIN;
|
|
5
|
+
|
|
6
|
+
-- Users table (extends existing authentication)
|
|
7
|
+
CREATE TABLE IF NOT EXISTS agentdev_users (
|
|
8
|
+
id SERIAL PRIMARY KEY,
|
|
9
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
10
|
+
password_hash VARCHAR(255) NOT NULL,
|
|
11
|
+
github_oauth_client_id TEXT,
|
|
12
|
+
github_oauth_client_secret_encrypted TEXT,
|
|
13
|
+
github_oauth_scopes TEXT[] DEFAULT ARRAY['repo', 'read:org', 'project'],
|
|
14
|
+
max_agents INT DEFAULT 3,
|
|
15
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
16
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_users_email ON agentdev_users(email);
|
|
20
|
+
|
|
21
|
+
-- Agents table (without current_ticket_id FK first)
|
|
22
|
+
CREATE TABLE IF NOT EXISTS agentdev_agents (
|
|
23
|
+
id VARCHAR(64) PRIMARY KEY,
|
|
24
|
+
user_id INT NOT NULL REFERENCES agentdev_users(id) ON DELETE CASCADE,
|
|
25
|
+
name VARCHAR(100) NOT NULL,
|
|
26
|
+
hostname VARCHAR(128),
|
|
27
|
+
status VARCHAR(20) DEFAULT 'offline' CHECK (status IN ('offline', 'idle', 'busy')),
|
|
28
|
+
current_ticket_id INT, -- FK will be added later
|
|
29
|
+
last_heartbeat TIMESTAMPTZ,
|
|
30
|
+
registered_at TIMESTAMPTZ DEFAULT NOW(),
|
|
31
|
+
capabilities JSONB DEFAULT '{}'::jsonb,
|
|
32
|
+
access_token_hash VARCHAR(255)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_agents_user ON agentdev_agents(user_id);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_agents_status ON agentdev_agents(status);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_agents_heartbeat ON agentdev_agents(last_heartbeat);
|
|
38
|
+
|
|
39
|
+
-- Tickets table (without assigned_agent_id FK first)
|
|
40
|
+
CREATE TABLE IF NOT EXISTS agentdev_tickets (
|
|
41
|
+
id SERIAL PRIMARY KEY,
|
|
42
|
+
github_issue_number INT NOT NULL,
|
|
43
|
+
github_repo VARCHAR(100) NOT NULL,
|
|
44
|
+
github_project_item_id VARCHAR(100),
|
|
45
|
+
status VARCHAR(20) DEFAULT 'todo' CHECK (status IN ('todo', 'assigned', 'in_progress', 'completed', 'failed')),
|
|
46
|
+
assigned_agent_id VARCHAR(64), -- FK will be added later
|
|
47
|
+
assigned_at TIMESTAMPTZ,
|
|
48
|
+
priority INT DEFAULT 5,
|
|
49
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
50
|
+
completed_at TIMESTAMPTZ,
|
|
51
|
+
error_message TEXT,
|
|
52
|
+
UNIQUE(github_repo, github_issue_number)
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_tickets_status ON agentdev_tickets(status);
|
|
56
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_tickets_assigned ON agentdev_tickets(assigned_agent_id);
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_tickets_priority ON agentdev_tickets(priority DESC);
|
|
58
|
+
|
|
59
|
+
-- Now add the circular foreign keys
|
|
60
|
+
DO $$
|
|
61
|
+
BEGIN
|
|
62
|
+
-- Add FK from agents to tickets
|
|
63
|
+
IF NOT EXISTS (
|
|
64
|
+
SELECT 1 FROM information_schema.table_constraints
|
|
65
|
+
WHERE constraint_name = 'fk_current_ticket'
|
|
66
|
+
AND table_name = 'agentdev_agents'
|
|
67
|
+
) THEN
|
|
68
|
+
ALTER TABLE agentdev_agents
|
|
69
|
+
ADD CONSTRAINT fk_current_ticket
|
|
70
|
+
FOREIGN KEY (current_ticket_id)
|
|
71
|
+
REFERENCES agentdev_tickets(id)
|
|
72
|
+
ON DELETE SET NULL
|
|
73
|
+
DEFERRABLE INITIALLY DEFERRED;
|
|
74
|
+
END IF;
|
|
75
|
+
|
|
76
|
+
-- Add FK from tickets to agents
|
|
77
|
+
IF NOT EXISTS (
|
|
78
|
+
SELECT 1 FROM information_schema.table_constraints
|
|
79
|
+
WHERE constraint_name = 'fk_assigned_agent'
|
|
80
|
+
AND table_name = 'agentdev_tickets'
|
|
81
|
+
) THEN
|
|
82
|
+
ALTER TABLE agentdev_tickets
|
|
83
|
+
ADD CONSTRAINT fk_assigned_agent
|
|
84
|
+
FOREIGN KEY (assigned_agent_id)
|
|
85
|
+
REFERENCES agentdev_agents(id)
|
|
86
|
+
ON DELETE SET NULL;
|
|
87
|
+
END IF;
|
|
88
|
+
END $$;
|
|
89
|
+
|
|
90
|
+
-- Agent logs table (optional - for persistent storage beyond Redis)
|
|
91
|
+
CREATE TABLE IF NOT EXISTS agentdev_logs (
|
|
92
|
+
id BIGSERIAL PRIMARY KEY,
|
|
93
|
+
agent_id VARCHAR(64) NOT NULL REFERENCES agentdev_agents(id) ON DELETE CASCADE,
|
|
94
|
+
ticket_id INT REFERENCES agentdev_tickets(id) ON DELETE CASCADE,
|
|
95
|
+
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
96
|
+
level VARCHAR(10) DEFAULT 'INFO' CHECK (level IN ('DEBUG', 'INFO', 'WARN', 'ERROR')),
|
|
97
|
+
content TEXT NOT NULL
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_logs_agent_time ON agentdev_logs(agent_id, timestamp DESC);
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_logs_ticket ON agentdev_logs(ticket_id);
|
|
102
|
+
|
|
103
|
+
-- Device authorization table (for OAuth device flow)
|
|
104
|
+
CREATE TABLE IF NOT EXISTS agentdev_device_codes (
|
|
105
|
+
device_code VARCHAR(64) PRIMARY KEY,
|
|
106
|
+
user_code VARCHAR(16) UNIQUE NOT NULL,
|
|
107
|
+
user_id INT REFERENCES agentdev_users(id) ON DELETE CASCADE,
|
|
108
|
+
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'denied', 'expired')),
|
|
109
|
+
agent_name VARCHAR(100),
|
|
110
|
+
agent_capabilities JSONB,
|
|
111
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
112
|
+
expires_at TIMESTAMPTZ NOT NULL
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_device_codes_user_code ON agentdev_device_codes(user_code);
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_device_codes_expires ON agentdev_device_codes(expires_at);
|
|
117
|
+
|
|
118
|
+
-- Auto-update updated_at timestamp
|
|
119
|
+
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
120
|
+
RETURNS TRIGGER AS $$
|
|
121
|
+
BEGIN
|
|
122
|
+
NEW.updated_at = NOW();
|
|
123
|
+
RETURN NEW;
|
|
124
|
+
END;
|
|
125
|
+
$$ language 'plpgsql';
|
|
126
|
+
|
|
127
|
+
DROP TRIGGER IF EXISTS update_agentdev_users_updated_at ON agentdev_users;
|
|
128
|
+
CREATE TRIGGER update_agentdev_users_updated_at BEFORE UPDATE ON agentdev_users
|
|
129
|
+
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
130
|
+
|
|
131
|
+
-- Grant permissions
|
|
132
|
+
GRANT ALL ON ALL TABLES IN SCHEMA public TO agentdev;
|
|
133
|
+
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO agentdev;
|
|
134
|
+
|
|
135
|
+
COMMIT;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
-- AgentDev Distributed System Database Schema
|
|
2
|
+
-- Run with: psql -U agentdev -d datatamer -f migrations/001_create_agentdev_schema.sql
|
|
3
|
+
|
|
4
|
+
BEGIN;
|
|
5
|
+
|
|
6
|
+
-- Users table (extends existing authentication)
|
|
7
|
+
CREATE TABLE IF NOT EXISTS agentdev_users (
|
|
8
|
+
id SERIAL PRIMARY KEY,
|
|
9
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
10
|
+
password_hash VARCHAR(255) NOT NULL,
|
|
11
|
+
github_oauth_client_id TEXT,
|
|
12
|
+
github_oauth_client_secret_encrypted TEXT,
|
|
13
|
+
github_oauth_scopes TEXT[] DEFAULT ARRAY['repo', 'read:org', 'project'],
|
|
14
|
+
max_agents INT DEFAULT 3,
|
|
15
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
16
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE INDEX idx_agentdev_users_email ON agentdev_users(email);
|
|
20
|
+
|
|
21
|
+
-- Agents table
|
|
22
|
+
CREATE TABLE IF NOT EXISTS agentdev_agents (
|
|
23
|
+
id VARCHAR(64) PRIMARY KEY,
|
|
24
|
+
user_id INT NOT NULL REFERENCES agentdev_users(id) ON DELETE CASCADE,
|
|
25
|
+
name VARCHAR(100) NOT NULL,
|
|
26
|
+
hostname VARCHAR(128),
|
|
27
|
+
status VARCHAR(20) DEFAULT 'offline' CHECK (status IN ('offline', 'idle', 'busy')),
|
|
28
|
+
current_ticket_id INT,
|
|
29
|
+
last_heartbeat TIMESTAMPTZ,
|
|
30
|
+
registered_at TIMESTAMPTZ DEFAULT NOW(),
|
|
31
|
+
capabilities JSONB DEFAULT '{}'::jsonb,
|
|
32
|
+
access_token_hash VARCHAR(255),
|
|
33
|
+
CONSTRAINT fk_current_ticket FOREIGN KEY (current_ticket_id) REFERENCES agentdev_tickets(id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE INDEX idx_agentdev_agents_user ON agentdev_agents(user_id);
|
|
37
|
+
CREATE INDEX idx_agentdev_agents_status ON agentdev_agents(status);
|
|
38
|
+
CREATE INDEX idx_agentdev_agents_heartbeat ON agentdev_agents(last_heartbeat);
|
|
39
|
+
|
|
40
|
+
-- Tickets table
|
|
41
|
+
CREATE TABLE IF NOT EXISTS agentdev_tickets (
|
|
42
|
+
id SERIAL PRIMARY KEY,
|
|
43
|
+
github_issue_number INT NOT NULL,
|
|
44
|
+
github_repo VARCHAR(100) NOT NULL,
|
|
45
|
+
github_project_item_id VARCHAR(100),
|
|
46
|
+
status VARCHAR(20) DEFAULT 'todo' CHECK (status IN ('todo', 'assigned', 'in_progress', 'completed', 'failed')),
|
|
47
|
+
assigned_agent_id VARCHAR(64) REFERENCES agentdev_agents(id) ON DELETE SET NULL,
|
|
48
|
+
assigned_at TIMESTAMPTZ,
|
|
49
|
+
priority INT DEFAULT 5,
|
|
50
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
51
|
+
completed_at TIMESTAMPTZ,
|
|
52
|
+
error_message TEXT,
|
|
53
|
+
UNIQUE(github_repo, github_issue_number)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
CREATE INDEX idx_agentdev_tickets_status ON agentdev_tickets(status);
|
|
57
|
+
CREATE INDEX idx_agentdev_tickets_assigned ON agentdev_tickets(assigned_agent_id);
|
|
58
|
+
CREATE INDEX idx_agentdev_tickets_priority ON agentdev_tickets(priority DESC);
|
|
59
|
+
|
|
60
|
+
-- Agent logs table (optional - for persistent storage beyond Redis)
|
|
61
|
+
CREATE TABLE IF NOT EXISTS agentdev_logs (
|
|
62
|
+
id BIGSERIAL PRIMARY KEY,
|
|
63
|
+
agent_id VARCHAR(64) NOT NULL REFERENCES agentdev_agents(id) ON DELETE CASCADE,
|
|
64
|
+
ticket_id INT REFERENCES agentdev_tickets(id) ON DELETE CASCADE,
|
|
65
|
+
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
66
|
+
level VARCHAR(10) DEFAULT 'INFO' CHECK (level IN ('DEBUG', 'INFO', 'WARN', 'ERROR')),
|
|
67
|
+
content TEXT NOT NULL
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
CREATE INDEX idx_agentdev_logs_agent_time ON agentdev_logs(agent_id, timestamp DESC);
|
|
71
|
+
CREATE INDEX idx_agentdev_logs_ticket ON agentdev_logs(ticket_id);
|
|
72
|
+
|
|
73
|
+
-- Device authorization table (for OAuth device flow)
|
|
74
|
+
CREATE TABLE IF NOT EXISTS agentdev_device_codes (
|
|
75
|
+
device_code VARCHAR(64) PRIMARY KEY,
|
|
76
|
+
user_code VARCHAR(16) UNIQUE NOT NULL,
|
|
77
|
+
user_id INT REFERENCES agentdev_users(id) ON DELETE CASCADE,
|
|
78
|
+
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'denied', 'expired')),
|
|
79
|
+
agent_name VARCHAR(100),
|
|
80
|
+
agent_capabilities JSONB,
|
|
81
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
82
|
+
expires_at TIMESTAMPTZ NOT NULL
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
CREATE INDEX idx_agentdev_device_codes_user_code ON agentdev_device_codes(user_code);
|
|
86
|
+
CREATE INDEX idx_agentdev_device_codes_expires ON agentdev_device_codes(expires_at);
|
|
87
|
+
|
|
88
|
+
-- Auto-update updated_at timestamp
|
|
89
|
+
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
90
|
+
RETURNS TRIGGER AS $$
|
|
91
|
+
BEGIN
|
|
92
|
+
NEW.updated_at = NOW();
|
|
93
|
+
RETURN NEW;
|
|
94
|
+
END;
|
|
95
|
+
$$ language 'plpgsql';
|
|
96
|
+
|
|
97
|
+
CREATE TRIGGER update_agentdev_users_updated_at BEFORE UPDATE ON agentdev_users
|
|
98
|
+
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
99
|
+
|
|
100
|
+
COMMIT;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
-- AgentDev Distributed System Database Schema
|
|
2
|
+
-- Fixed version without circular foreign key dependencies
|
|
3
|
+
|
|
4
|
+
BEGIN;
|
|
5
|
+
|
|
6
|
+
-- Users table (extends existing authentication)
|
|
7
|
+
CREATE TABLE IF NOT EXISTS agentdev_users (
|
|
8
|
+
id SERIAL PRIMARY KEY,
|
|
9
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
10
|
+
password_hash VARCHAR(255) NOT NULL,
|
|
11
|
+
github_oauth_client_id TEXT,
|
|
12
|
+
github_oauth_client_secret_encrypted TEXT,
|
|
13
|
+
github_oauth_scopes TEXT[] DEFAULT ARRAY['repo', 'read:org', 'project'],
|
|
14
|
+
max_agents INT DEFAULT 3,
|
|
15
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
16
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_users_email ON agentdev_users(email);
|
|
20
|
+
|
|
21
|
+
-- Agents table (without current_ticket_id FK first)
|
|
22
|
+
CREATE TABLE IF NOT EXISTS agentdev_agents (
|
|
23
|
+
id VARCHAR(64) PRIMARY KEY,
|
|
24
|
+
user_id INT NOT NULL REFERENCES agentdev_users(id) ON DELETE CASCADE,
|
|
25
|
+
name VARCHAR(100) NOT NULL,
|
|
26
|
+
hostname VARCHAR(128),
|
|
27
|
+
status VARCHAR(20) DEFAULT 'offline' CHECK (status IN ('offline', 'idle', 'busy')),
|
|
28
|
+
current_ticket_id INT, -- FK will be added later
|
|
29
|
+
last_heartbeat TIMESTAMPTZ,
|
|
30
|
+
registered_at TIMESTAMPTZ DEFAULT NOW(),
|
|
31
|
+
capabilities JSONB DEFAULT '{}'::jsonb,
|
|
32
|
+
access_token_hash VARCHAR(255)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_agents_user ON agentdev_agents(user_id);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_agents_status ON agentdev_agents(status);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_agents_heartbeat ON agentdev_agents(last_heartbeat);
|
|
38
|
+
|
|
39
|
+
-- Tickets table (without assigned_agent_id FK first)
|
|
40
|
+
CREATE TABLE IF NOT EXISTS agentdev_tickets (
|
|
41
|
+
id SERIAL PRIMARY KEY,
|
|
42
|
+
github_issue_number INT NOT NULL,
|
|
43
|
+
github_repo VARCHAR(100) NOT NULL,
|
|
44
|
+
github_project_item_id VARCHAR(100),
|
|
45
|
+
status VARCHAR(20) DEFAULT 'todo' CHECK (status IN ('todo', 'assigned', 'in_progress', 'completed', 'failed')),
|
|
46
|
+
assigned_agent_id VARCHAR(64), -- FK will be added later
|
|
47
|
+
assigned_at TIMESTAMPTZ,
|
|
48
|
+
priority INT DEFAULT 5,
|
|
49
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
50
|
+
completed_at TIMESTAMPTZ,
|
|
51
|
+
error_message TEXT,
|
|
52
|
+
UNIQUE(github_repo, github_issue_number)
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_tickets_status ON agentdev_tickets(status);
|
|
56
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_tickets_assigned ON agentdev_tickets(assigned_agent_id);
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_tickets_priority ON agentdev_tickets(priority DESC);
|
|
58
|
+
|
|
59
|
+
-- Now add the circular foreign keys
|
|
60
|
+
DO $$
|
|
61
|
+
BEGIN
|
|
62
|
+
-- Add FK from agents to tickets
|
|
63
|
+
IF NOT EXISTS (
|
|
64
|
+
SELECT 1 FROM information_schema.table_constraints
|
|
65
|
+
WHERE constraint_name = 'fk_current_ticket'
|
|
66
|
+
AND table_name = 'agentdev_agents'
|
|
67
|
+
) THEN
|
|
68
|
+
ALTER TABLE agentdev_agents
|
|
69
|
+
ADD CONSTRAINT fk_current_ticket
|
|
70
|
+
FOREIGN KEY (current_ticket_id)
|
|
71
|
+
REFERENCES agentdev_tickets(id)
|
|
72
|
+
ON DELETE SET NULL
|
|
73
|
+
DEFERRABLE INITIALLY DEFERRED;
|
|
74
|
+
END IF;
|
|
75
|
+
|
|
76
|
+
-- Add FK from tickets to agents
|
|
77
|
+
IF NOT EXISTS (
|
|
78
|
+
SELECT 1 FROM information_schema.table_constraints
|
|
79
|
+
WHERE constraint_name = 'fk_assigned_agent'
|
|
80
|
+
AND table_name = 'agentdev_tickets'
|
|
81
|
+
) THEN
|
|
82
|
+
ALTER TABLE agentdev_tickets
|
|
83
|
+
ADD CONSTRAINT fk_assigned_agent
|
|
84
|
+
FOREIGN KEY (assigned_agent_id)
|
|
85
|
+
REFERENCES agentdev_agents(id)
|
|
86
|
+
ON DELETE SET NULL;
|
|
87
|
+
END IF;
|
|
88
|
+
END $$;
|
|
89
|
+
|
|
90
|
+
-- Agent logs table (optional - for persistent storage beyond Redis)
|
|
91
|
+
CREATE TABLE IF NOT EXISTS agentdev_logs (
|
|
92
|
+
id BIGSERIAL PRIMARY KEY,
|
|
93
|
+
agent_id VARCHAR(64) NOT NULL REFERENCES agentdev_agents(id) ON DELETE CASCADE,
|
|
94
|
+
ticket_id INT REFERENCES agentdev_tickets(id) ON DELETE CASCADE,
|
|
95
|
+
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
96
|
+
level VARCHAR(10) DEFAULT 'INFO' CHECK (level IN ('DEBUG', 'INFO', 'WARN', 'ERROR')),
|
|
97
|
+
content TEXT NOT NULL
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_logs_agent_time ON agentdev_logs(agent_id, timestamp DESC);
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_logs_ticket ON agentdev_logs(ticket_id);
|
|
102
|
+
|
|
103
|
+
-- Device authorization table (for OAuth device flow)
|
|
104
|
+
CREATE TABLE IF NOT EXISTS agentdev_device_codes (
|
|
105
|
+
device_code VARCHAR(64) PRIMARY KEY,
|
|
106
|
+
user_code VARCHAR(16) UNIQUE NOT NULL,
|
|
107
|
+
user_id INT REFERENCES agentdev_users(id) ON DELETE CASCADE,
|
|
108
|
+
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'denied', 'expired')),
|
|
109
|
+
agent_name VARCHAR(100),
|
|
110
|
+
agent_capabilities JSONB,
|
|
111
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
112
|
+
expires_at TIMESTAMPTZ NOT NULL
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_device_codes_user_code ON agentdev_device_codes(user_code);
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_device_codes_expires ON agentdev_device_codes(expires_at);
|
|
117
|
+
|
|
118
|
+
-- Auto-update updated_at timestamp
|
|
119
|
+
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
120
|
+
RETURNS TRIGGER AS $$
|
|
121
|
+
BEGIN
|
|
122
|
+
NEW.updated_at = NOW();
|
|
123
|
+
RETURN NEW;
|
|
124
|
+
END;
|
|
125
|
+
$$ language 'plpgsql';
|
|
126
|
+
|
|
127
|
+
DROP TRIGGER IF EXISTS update_agentdev_users_updated_at ON agentdev_users;
|
|
128
|
+
CREATE TRIGGER update_agentdev_users_updated_at BEFORE UPDATE ON agentdev_users
|
|
129
|
+
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
130
|
+
|
|
131
|
+
-- Grant permissions
|
|
132
|
+
GRANT ALL ON ALL TABLES IN SCHEMA public TO agentdev;
|
|
133
|
+
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO agentdev;
|
|
134
|
+
|
|
135
|
+
COMMIT;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Migration: Add GitHub token column to users table
|
|
2
|
+
-- Date: 2026-02-07
|
|
3
|
+
|
|
4
|
+
-- Add github_token_encrypted column to agentdev_users table
|
|
5
|
+
ALTER TABLE agentdev_users
|
|
6
|
+
ADD COLUMN IF NOT EXISTS github_token_encrypted TEXT;
|
|
7
|
+
|
|
8
|
+
-- Add index for faster lookups (optional but recommended)
|
|
9
|
+
CREATE INDEX IF NOT EXISTS idx_users_github_token
|
|
10
|
+
ON agentdev_users(id)
|
|
11
|
+
WHERE github_token_encrypted IS NOT NULL;
|
|
12
|
+
|
|
13
|
+
-- Verify column was added
|
|
14
|
+
SELECT column_name, data_type, is_nullable
|
|
15
|
+
FROM information_schema.columns
|
|
16
|
+
WHERE table_name = 'agentdev_users'
|
|
17
|
+
AND column_name = 'github_token_encrypted';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- Migration: Add agent logs table
|
|
2
|
+
-- Date: 2026-02-07
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS agentdev_agent_logs (
|
|
5
|
+
id BIGSERIAL PRIMARY KEY,
|
|
6
|
+
agent_id VARCHAR(64) NOT NULL,
|
|
7
|
+
ticket_number INT,
|
|
8
|
+
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
9
|
+
level VARCHAR(10) DEFAULT 'INFO',
|
|
10
|
+
content TEXT NOT NULL
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
CREATE INDEX IF NOT EXISTS idx_agent_logs_agent_time
|
|
14
|
+
ON agentdev_agent_logs(agent_id, timestamp DESC);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_agent_logs_timestamp
|
|
17
|
+
ON agentdev_agent_logs(timestamp DESC);
|
|
18
|
+
|
|
19
|
+
-- Verify table was created
|
|
20
|
+
SELECT table_name, column_name, data_type
|
|
21
|
+
FROM information_schema.columns
|
|
22
|
+
WHERE table_name = 'agentdev_agent_logs'
|
|
23
|
+
ORDER BY ordinal_position;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Remove OAuth client ID/secret columns from agentdev_users
|
|
2
|
+
-- Users only need a GitHub Personal Access Token (github_token_encrypted)
|
|
3
|
+
|
|
4
|
+
BEGIN;
|
|
5
|
+
|
|
6
|
+
ALTER TABLE agentdev_users
|
|
7
|
+
DROP COLUMN IF EXISTS github_oauth_client_id,
|
|
8
|
+
DROP COLUMN IF EXISTS github_oauth_client_secret_encrypted,
|
|
9
|
+
DROP COLUMN IF EXISTS github_oauth_scopes;
|
|
10
|
+
|
|
11
|
+
COMMIT;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
BEGIN;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS agentdev_projects (
|
|
4
|
+
id SERIAL PRIMARY KEY,
|
|
5
|
+
name VARCHAR(100) NOT NULL,
|
|
6
|
+
github_org VARCHAR(100) NOT NULL,
|
|
7
|
+
project_number INT NOT NULL,
|
|
8
|
+
github_project_id VARCHAR(100) NOT NULL,
|
|
9
|
+
status_field_id VARCHAR(100) NOT NULL,
|
|
10
|
+
status_options JSONB NOT NULL DEFAULT '{}',
|
|
11
|
+
created_by INT REFERENCES agentdev_users(id),
|
|
12
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
13
|
+
UNIQUE(github_org, project_number)
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
-- Seed the existing hardcoded project
|
|
17
|
+
INSERT INTO agentdev_projects (name, github_org, project_number, github_project_id, status_field_id, status_options)
|
|
18
|
+
VALUES (
|
|
19
|
+
'DataTamer',
|
|
20
|
+
'data-tamer',
|
|
21
|
+
1,
|
|
22
|
+
'PVT_kwDOCJIWbs4AnuSZ',
|
|
23
|
+
'PVTSSF_lADOCJIWbs4AnuSZzgfaWGs',
|
|
24
|
+
'{"TODO":"f75ad846","IN_PROGRESS":"47fc9ee4","TEST":"c48bc058","DONE":"98236657"}'
|
|
25
|
+
) ON CONFLICT DO NOTHING;
|
|
26
|
+
|
|
27
|
+
-- Add project_id to agents (nullable for backwards compat, then backfill)
|
|
28
|
+
ALTER TABLE agentdev_agents ADD COLUMN IF NOT EXISTS project_id INT REFERENCES agentdev_projects(id) ON DELETE SET NULL;
|
|
29
|
+
|
|
30
|
+
-- Add project_id to tickets
|
|
31
|
+
ALTER TABLE agentdev_tickets ADD COLUMN IF NOT EXISTS project_id INT REFERENCES agentdev_projects(id) ON DELETE SET NULL;
|
|
32
|
+
|
|
33
|
+
-- Backfill existing rows to project 1
|
|
34
|
+
UPDATE agentdev_agents SET project_id = 1 WHERE project_id IS NULL;
|
|
35
|
+
UPDATE agentdev_tickets SET project_id = 1 WHERE project_id IS NULL;
|
|
36
|
+
|
|
37
|
+
-- Indexes
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_agents_project ON agentdev_agents(project_id);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_tickets_project ON agentdev_tickets(project_id);
|
|
40
|
+
|
|
41
|
+
GRANT ALL ON ALL TABLES IN SCHEMA public TO agentdev;
|
|
42
|
+
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO agentdev;
|
|
43
|
+
|
|
44
|
+
COMMIT;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
BEGIN;
|
|
2
|
+
|
|
3
|
+
ALTER TABLE agentdev_projects ADD COLUMN IF NOT EXISTS repositories JSONB NOT NULL DEFAULT '[]';
|
|
4
|
+
|
|
5
|
+
-- Seed existing DataTamer project with current repo list
|
|
6
|
+
UPDATE agentdev_projects
|
|
7
|
+
SET repositories = '["data-tamer-dashboard","tamer_service","datatamer.ai","super_agent","consumer_service","agent_service","agentdev-webui","data-tamer-mobile","production_k3s","local_k3s"]'
|
|
8
|
+
WHERE github_org = 'data-tamer' AND project_number = 1;
|
|
9
|
+
|
|
10
|
+
GRANT ALL ON ALL TABLES IN SCHEMA public TO agentdev;
|
|
11
|
+
|
|
12
|
+
COMMIT;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
BEGIN;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS agentdev_notifications (
|
|
4
|
+
id BIGSERIAL PRIMARY KEY,
|
|
5
|
+
user_id INT NOT NULL REFERENCES agentdev_users(id) ON DELETE CASCADE,
|
|
6
|
+
type VARCHAR(50) NOT NULL DEFAULT 'ticket-completed',
|
|
7
|
+
title VARCHAR(255) NOT NULL,
|
|
8
|
+
message TEXT,
|
|
9
|
+
metadata JSONB DEFAULT '{}',
|
|
10
|
+
read BOOLEAN NOT NULL DEFAULT FALSE,
|
|
11
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_agentdev_notifications_user_unread
|
|
15
|
+
ON agentdev_notifications (user_id, read, created_at DESC);
|
|
16
|
+
|
|
17
|
+
GRANT ALL ON agentdev_notifications TO agentdev;
|
|
18
|
+
GRANT ALL ON agentdev_notifications_id_seq TO agentdev;
|
|
19
|
+
|
|
20
|
+
COMMIT;
|