feat: Unified Messaging System — kommunikation plugin, AI/Proactive/System participants, MessageSidebar, Rich Content Renderer
Phase 1: Backend plugin kommunikation (13 files, 10 tables, REST API, WebSocket, RBAC, DMS Bridge, Participant Registry, Mini-App Registry, Search Provider) Phase 2: AI plugins as participants (ai_assistant + ai_proactive dock as participants, heartbeat job) Phase 3: system_notif plugin (system events → chat messages, pinned System room) Phase 4: Frontend MessageSidebar (replaces AISidebar, same design, comm API client, WebSocket hook, commStore) Phase 5: Rich Content Block Renderer (11 components: Markdown, HTML, Image, Audio, Video, File, ActionCard, ContactCard, MiniApp, BlockRenderer) BasePlugin: added services property + _container in on_activate
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
-- kommunikation plugin initial migration: creates all 10 tables
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_conversations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
title VARCHAR(255),
|
||||
title_set_by UUID,
|
||||
is_pinned BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_locked BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
locked_by VARCHAR(100),
|
||||
is_direct BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
is_archived BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_by UUID,
|
||||
created_by_type VARCHAR(20) NOT NULL DEFAULT 'user',
|
||||
last_msg_at TIMESTAMPTZ,
|
||||
last_msg_preview TEXT,
|
||||
last_msg_sender_type VARCHAR(50),
|
||||
metadata JSONB NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_conversations_tenant ON comm_conversations(tenant_id);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_conversations_tenant_pinned ON comm_conversations(tenant_id, is_pinned);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_conversations_last_msg ON comm_conversations(tenant_id, last_msg_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_participants (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
conversation_id UUID NOT NULL REFERENCES comm_conversations(id) ON DELETE CASCADE,
|
||||
participant_id UUID,
|
||||
participant_type VARCHAR(50) NOT NULL,
|
||||
display_name VARCHAR(255),
|
||||
role VARCHAR(20) NOT NULL DEFAULT 'member',
|
||||
joined_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
left_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
UNIQUE(conversation_id, participant_id, participant_type)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_participants_tenant_conv ON comm_participants(tenant_id, conversation_id);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_participants_tenant_user ON comm_participants(tenant_id, participant_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_messages (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
conversation_id UUID NOT NULL REFERENCES comm_conversations(id) ON DELETE CASCADE,
|
||||
sender_id UUID,
|
||||
sender_type VARCHAR(50) NOT NULL,
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
content_format VARCHAR(20) NOT NULL DEFAULT 'text',
|
||||
metadata JSONB NOT NULL DEFAULT '{}',
|
||||
reply_to_id UUID REFERENCES comm_messages(id) ON DELETE SET NULL,
|
||||
is_pinned BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
read_at TIMESTAMPTZ,
|
||||
edited_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_messages_tenant_conv ON comm_messages(tenant_id, conversation_id, created_at);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_messages_tenant_sender ON comm_messages(tenant_id, sender_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_message_blocks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
message_id UUID NOT NULL REFERENCES comm_messages(id) ON DELETE CASCADE,
|
||||
block_type VARCHAR(50) NOT NULL,
|
||||
block_data JSONB NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_blocks_tenant_msg ON comm_message_blocks(tenant_id, message_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_message_attachments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
message_id UUID NOT NULL REFERENCES comm_messages(id) ON DELETE CASCADE,
|
||||
file_id UUID,
|
||||
file_source VARCHAR(10) NOT NULL DEFAULT 'comm',
|
||||
file_name VARCHAR(255) NOT NULL,
|
||||
file_type VARCHAR(255) NOT NULL,
|
||||
file_size INTEGER,
|
||||
thumbnail_path VARCHAR(1024),
|
||||
metadata JSONB NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_attachments_tenant_msg ON comm_message_attachments(tenant_id, message_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_message_reactions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
message_id UUID NOT NULL REFERENCES comm_messages(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL,
|
||||
emoji VARCHAR(50) NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
UNIQUE(message_id, user_id, emoji)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_reactions_tenant_msg ON comm_message_reactions(tenant_id, message_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_message_reads (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
conversation_id UUID NOT NULL REFERENCES comm_conversations(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL,
|
||||
last_read_msg_id UUID REFERENCES comm_messages(id) ON DELETE SET NULL,
|
||||
last_read_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
UNIQUE(conversation_id, user_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_reads_tenant_user ON comm_message_reads(tenant_id, user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_conversation_pins (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
conversation_id UUID NOT NULL REFERENCES comm_conversations(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL,
|
||||
pinned_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
UNIQUE(conversation_id, user_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_pins_tenant_user ON comm_conversation_pins(tenant_id, user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_conversation_mutes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
conversation_id UUID NOT NULL REFERENCES comm_conversations(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL,
|
||||
muted_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
UNIQUE(conversation_id, user_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_mutes_tenant_user ON comm_conversation_mutes(tenant_id, user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS comm_message_edits (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
message_id UUID NOT NULL REFERENCES comm_messages(id) ON DELETE CASCADE,
|
||||
old_content TEXT NOT NULL,
|
||||
old_blocks JSONB NOT NULL DEFAULT '[]',
|
||||
edited_by UUID NOT NULL,
|
||||
edited_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_comm_edits_tenant_msg ON comm_message_edits(tenant_id, message_id);
|
||||
Reference in New Issue
Block a user