Files
microdao-daarion/services/city-service/migrations.py

168 lines
9.6 KiB
Python

import asyncpg
import os
import logging
logger = logging.getLogger(__name__)
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://postgres:postgres@localhost:5432/daarion")
async def run_migrations():
conn = None
try:
conn = await asyncpg.connect(DATABASE_URL)
# Add logo_url and banner_url to microdaos table (previous task)
await conn.execute("""
ALTER TABLE microdaos
ADD COLUMN IF NOT EXISTS logo_url TEXT,
ADD COLUMN IF NOT EXISTS banner_url TEXT;
""")
# Add logo_url and banner_url to city_rooms table (previous task)
await conn.execute("""
ALTER TABLE city_rooms
ADD COLUMN IF NOT EXISTS logo_url TEXT,
ADD COLUMN IF NOT EXISTS banner_url TEXT;
""")
# NEW: Add crew_team_key to agents table (TASK 044)
await conn.execute("""
ALTER TABLE agents
ADD COLUMN IF NOT EXISTS crew_team_key TEXT;
""")
logger.info("Migration: Added crew_team_key to agents table.")
# TASK 044: Add room_role, is_public, sort_order to city_rooms table
await conn.execute("""
ALTER TABLE city_rooms
ADD COLUMN IF NOT EXISTS room_role TEXT,
ADD COLUMN IF NOT EXISTS is_public BOOLEAN DEFAULT TRUE,
ADD COLUMN IF NOT EXISTS sort_order INTEGER DEFAULT 100;
""")
logger.info("Migration: Added room_role, is_public, sort_order to city_rooms table.")
# ROOMS_LAYER_RESTORE: Add owner_type, owner_id, space_scope, visibility, room_type
await conn.execute("""
ALTER TABLE city_rooms
ADD COLUMN IF NOT EXISTS room_type TEXT DEFAULT 'chat',
ADD COLUMN IF NOT EXISTS owner_type TEXT DEFAULT 'city',
ADD COLUMN IF NOT EXISTS owner_id TEXT,
ADD COLUMN IF NOT EXISTS space_scope TEXT DEFAULT 'city',
ADD COLUMN IF NOT EXISTS visibility TEXT DEFAULT 'public-city';
""")
logger.info("Migration: Added room_type, owner_type, owner_id, space_scope, visibility to city_rooms table.")
# TASK C2: Create nodes table with owner_microdao (replaces node_cache for ontology)
await conn.execute("""
CREATE TABLE IF NOT EXISTS nodes (
id TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
hostname TEXT,
owner_microdao_id TEXT REFERENCES microdaos(id),
node_type TEXT,
environment TEXT DEFAULT 'unknown',
cpu_cores INTEGER,
ram_gb INTEGER,
gpu_count INTEGER DEFAULT 0,
disk_gb INTEGER,
status TEXT DEFAULT 'unknown',
guardian_agent_id TEXT,
steward_agent_id TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
""")
logger.info("Migration: Created nodes table with owner_microdao.")
# TASK C3: Insert NODE1 and NODE2 if not exist
await conn.execute("""
INSERT INTO nodes (id, display_name, hostname, owner_microdao_id, node_type, environment, status, guardian_agent_id, steward_agent_id)
VALUES
('node-1-hetzner-gex44', 'Hetzner GEX44 Production', '144.76.224.179', 'dao_daarion', 'compute', 'production', 'online', 'monitor-node1', 'node-steward-node1'),
('node-2-macbook-m4max', 'MacBook Pro M4 Max', '192.168.1.33', 'dao_daarion', 'hybrid', 'development', 'online', 'monitor-node2', 'node-steward-node2')
ON CONFLICT (id) DO UPDATE SET
display_name = EXCLUDED.display_name,
hostname = EXCLUDED.hostname,
owner_microdao_id = EXCLUDED.owner_microdao_id,
node_type = EXCLUDED.node_type,
environment = EXCLUDED.environment,
guardian_agent_id = EXCLUDED.guardian_agent_id,
steward_agent_id = EXCLUDED.steward_agent_id,
updated_at = NOW();
""")
logger.info("Migration: Inserted/updated NODE1 and NODE2 in nodes table.")
# =========================================================================
# ROOMS LAYER RESTORE (TASK_PHASE_ROOMS_LAYER_RESTORE_AND_MATRIX_INTEGRATION)
# =========================================================================
# Seed City Rooms (8 standard rooms)
await conn.execute("""
INSERT INTO city_rooms (id, slug, name, description, room_type, owner_type, owner_id, space_scope, visibility, is_public, sort_order, created_at, updated_at)
VALUES
(gen_random_uuid(), 'general', 'General', 'Main city chat room for all citizens', 'chat', 'city', 'daarion', 'city', 'public-city', true, 1, NOW(), NOW()),
(gen_random_uuid(), 'welcome', 'Welcome', 'Welcome new citizens to DAARION City', 'chat', 'city', 'daarion', 'city', 'public-city', true, 2, NOW(), NOW()),
(gen_random_uuid(), 'leadership-hall', 'Leadership Hall', 'City governance and leadership discussions', 'chat', 'city', 'daarion', 'city', 'public-city', true, 3, NOW(), NOW()),
(gen_random_uuid(), 'builders', 'Builders', 'Builders and developers community', 'chat', 'city', 'daarion', 'city', 'public-city', true, 4, NOW(), NOW()),
(gen_random_uuid(), 'science-lab', 'Science Lab', 'Research, AI, and innovation discussions', 'chat', 'city', 'daarion', 'city', 'public-city', true, 5, NOW(), NOW()),
(gen_random_uuid(), 'security-bureau', 'Security Bureau', 'Security and safety discussions', 'chat', 'city', 'daarion', 'city', 'public-city', true, 6, NOW(), NOW()),
(gen_random_uuid(), 'economics-square', 'Economics Square', 'Economics, tokenomics, and finance', 'chat', 'city', 'daarion', 'city', 'public-city', true, 7, NOW(), NOW()),
(gen_random_uuid(), 'announcements', 'Announcements', 'Official city announcements', 'broadcast', 'city', 'daarion', 'city', 'public-city', true, 8, NOW(), NOW())
ON CONFLICT (slug) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
room_type = EXCLUDED.room_type,
is_public = EXCLUDED.is_public,
sort_order = EXCLUDED.sort_order,
updated_at = NOW();
""")
logger.info("Migration: Seeded 8 City Rooms.")
# Seed MicroDAO Rooms for DAARION root DAO
await conn.execute("""
INSERT INTO city_rooms (id, slug, name, description, room_type, owner_type, owner_id, space_scope, visibility, is_public, room_role, sort_order, created_at, updated_at)
VALUES
(gen_random_uuid(), 'daarion-lobby', 'DAARION Lobby', 'Main lobby for DAARION DAO', 'chat', 'microdao', 'dao_daarion', 'microdao', 'public-city', true, 'primary', 1, NOW(), NOW()),
(gen_random_uuid(), 'daarion-governance', 'DAARION Governance', 'Governance and voting discussions', 'chat', 'microdao', 'dao_daarion', 'microdao', 'members', false, 'governance', 2, NOW(), NOW()),
(gen_random_uuid(), 'daarion-news', 'DAARION News', 'News and updates from DAARION', 'broadcast', 'microdao', 'dao_daarion', 'microdao', 'public-city', true, 'news', 3, NOW(), NOW()),
(gen_random_uuid(), 'daarion-builders', 'DAARION Builders', 'Development and technical discussions', 'chat', 'microdao', 'dao_daarion', 'microdao', 'members', false, 'builders', 4, NOW(), NOW()),
(gen_random_uuid(), 'daarion-help', 'DAARION Help', 'Help and support for DAARION members', 'chat', 'microdao', 'dao_daarion', 'microdao', 'public-city', true, 'help', 5, NOW(), NOW())
ON CONFLICT (slug) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
room_role = EXCLUDED.room_role,
is_public = EXCLUDED.is_public,
sort_order = EXCLUDED.sort_order,
updated_at = NOW();
""")
logger.info("Migration: Seeded 5 MicroDAO Rooms for DAARION.")
# Seed Node Support Rooms
await conn.execute("""
INSERT INTO city_rooms (id, slug, name, description, room_type, owner_type, owner_id, space_scope, visibility, is_public, room_role, created_at, updated_at)
VALUES
(gen_random_uuid(), 'node-support-node1', 'NODE1 Support', 'Support room for Hetzner GEX44 Production node', 'node-support', 'node', 'node-1-hetzner-gex44', 'node', 'members', false, 'support', NOW(), NOW()),
(gen_random_uuid(), 'node-support-node2', 'NODE2 Support', 'Support room for MacBook Pro M4 Max node', 'node-support', 'node', 'node-2-macbook-m4max', 'node', 'members', false, 'support', NOW(), NOW())
ON CONFLICT (slug) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
room_role = EXCLUDED.room_role,
updated_at = NOW();
""")
logger.info("Migration: Seeded 2 Node Support Rooms.")
# Update public agents to be visible as citizens
await conn.execute("""
UPDATE agents SET is_public = true
WHERE gov_level IN ('city_governance', 'district_lead', 'orchestrator', 'core_team')
OR kind IN ('civic', 'governance', 'orchestrator');
""")
logger.info("Migration: Updated public agents for Citizens Layer.")
except Exception as e:
logger.error(f"Error running migrations: {e}")
raise
finally:
if conn:
await conn.close()