Files
microdao-daarion/migrations/008_create_microdao_core.sql
Apple 3de3c8cb36 feat: Add presence heartbeat for Matrix online status
- matrix-gateway: POST /internal/matrix/presence/online endpoint
- usePresenceHeartbeat hook with activity tracking
- Auto away after 5 min inactivity
- Offline on page close/visibility change
- Integrated in MatrixChatRoom component
2025-11-27 00:19:40 -08:00

197 lines
7.2 KiB
PL/PgSQL

-- ============================================================================
-- Migration 008: microDAO Core Tables
-- Phase 7: microDAO Console (MVP)
-- ============================================================================
-- ============================================================================
-- Table: microdaos
-- Purpose: MicroDAO entities (communities, organizations, teams)
-- ============================================================================
CREATE TABLE IF NOT EXISTS microdaos (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
external_id TEXT NOT NULL UNIQUE,
slug TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
description TEXT,
owner_user_id UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_microdaos_slug ON microdaos(slug);
CREATE INDEX idx_microdaos_owner_user_id ON microdaos(owner_user_id);
CREATE INDEX idx_microdaos_is_active ON microdaos(is_active);
COMMENT ON TABLE microdaos IS 'MicroDAO entities (communities, organizations)';
COMMENT ON COLUMN microdaos.external_id IS 'External identifier like microdao:7';
COMMENT ON COLUMN microdaos.slug IS 'URL-friendly slug like daarion-city';
-- ============================================================================
-- Table: microdao_members
-- Purpose: Members of microDAOs with roles
-- ============================================================================
CREATE TABLE IF NOT EXISTS microdao_members (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
microdao_id UUID NOT NULL REFERENCES microdaos(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
role TEXT NOT NULL,
joined_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(microdao_id, user_id)
);
CREATE INDEX idx_microdao_members_user_id ON microdao_members(user_id);
CREATE INDEX idx_microdao_members_microdao_id ON microdao_members(microdao_id);
CREATE INDEX idx_microdao_members_microdao_id_role ON microdao_members(microdao_id, role);
COMMENT ON TABLE microdao_members IS 'Members of microDAOs with roles';
COMMENT ON COLUMN microdao_members.role IS 'owner, admin, member, guest';
-- ============================================================================
-- Table: microdao_treasury
-- Purpose: Token balances for microDAOs
-- ============================================================================
CREATE TABLE IF NOT EXISTS microdao_treasury (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
microdao_id UUID NOT NULL REFERENCES microdaos(id) ON DELETE CASCADE,
token_symbol TEXT NOT NULL,
balance NUMERIC(30, 8) NOT NULL DEFAULT 0,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(microdao_id, token_symbol)
);
CREATE INDEX idx_microdao_treasury_microdao_id ON microdao_treasury(microdao_id);
COMMENT ON TABLE microdao_treasury IS 'Token balances for microDAOs';
COMMENT ON COLUMN microdao_treasury.balance IS 'Token balance with 8 decimal precision';
-- ============================================================================
-- Table: microdao_settings
-- Purpose: Key-value settings for microDAOs
-- ============================================================================
CREATE TABLE IF NOT EXISTS microdao_settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
microdao_id UUID NOT NULL REFERENCES microdaos(id) ON DELETE CASCADE,
key TEXT NOT NULL,
value JSONB,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(microdao_id, key)
);
CREATE INDEX idx_microdao_settings_microdao_id ON microdao_settings(microdao_id);
COMMENT ON TABLE microdao_settings IS 'Key-value settings for microDAOs';
COMMENT ON COLUMN microdao_settings.key IS 'visibility, join_mode, default_agent_id, etc.';
-- ============================================================================
-- Update Trigger: microdaos.updated_at
-- ============================================================================
CREATE OR REPLACE FUNCTION update_microdaos_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_update_microdaos_updated_at
BEFORE UPDATE ON microdaos
FOR EACH ROW
EXECUTE FUNCTION update_microdaos_updated_at();
-- ============================================================================
-- Seed Data: Sample microDAOs
-- ============================================================================
-- Insert DAARION microDAO
INSERT INTO microdaos (external_id, slug, name, description, owner_user_id)
SELECT
'microdao:daarion',
'daarion-city',
'DAARION Core',
'Децентралізована платформа для AI-агентів та microDAO',
id
FROM users
WHERE email = 'admin@daarion.xyz' OR id = (SELECT id FROM users LIMIT 1)
LIMIT 1
ON CONFLICT (external_id) DO NOTHING;
-- Add owner as member with owner role
INSERT INTO microdao_members (microdao_id, user_id, role)
SELECT
m.id,
m.owner_user_id,
'owner'
FROM microdaos m
WHERE m.external_id = 'microdao:daarion'
ON CONFLICT (microdao_id, user_id) DO NOTHING;
-- Initialize treasury with DAARION token
INSERT INTO microdao_treasury (microdao_id, token_symbol, balance)
SELECT
id,
'DAARION',
1000000.0
FROM microdaos
WHERE external_id = 'microdao:daarion'
ON CONFLICT (microdao_id, token_symbol) DO NOTHING;
-- Add default settings
INSERT INTO microdao_settings (microdao_id, key, value)
SELECT
id,
'visibility',
'"public"'::jsonb
FROM microdaos
WHERE external_id = 'microdao:daarion'
ON CONFLICT (microdao_id, key) DO NOTHING;
INSERT INTO microdao_settings (microdao_id, key, value)
SELECT
id,
'join_mode',
'"request"'::jsonb
FROM microdaos
WHERE external_id = 'microdao:daarion'
ON CONFLICT (microdao_id, key) DO NOTHING;
-- ============================================================================
-- Link existing agents to DAARION microDAO (if not already linked)
-- ============================================================================
UPDATE agents
SET microdao_id = (SELECT id FROM microdaos WHERE external_id = 'microdao:daarion' LIMIT 1)
WHERE external_id IN ('agent:sofia', 'agent:alex', 'agent:guardian')
AND microdao_id IS NULL;
-- ============================================================================
-- Grants
-- ============================================================================
GRANT SELECT, INSERT, UPDATE, DELETE ON microdaos TO postgres;
GRANT SELECT, INSERT, UPDATE, DELETE ON microdao_members TO postgres;
GRANT SELECT, INSERT, UPDATE, DELETE ON microdao_treasury TO postgres;
GRANT SELECT, INSERT, UPDATE, DELETE ON microdao_settings TO postgres;
-- ============================================================================
-- Migration Complete
-- ============================================================================
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_name IN ('microdaos', 'microdao_members', 'microdao_treasury', 'microdao_settings')
) THEN
RAISE NOTICE 'Migration 008: microDAO Core Tables created successfully';
ELSE
RAISE EXCEPTION 'Migration 008: Failed to create tables';
END IF;
END $$;