chore: consolidate migrations 6.1.1-6.1.3 into 6.1.0_enterprise_suite
All checks were successful
GBCI Bundle / build-bundle (push) Has been skipped
GBCI / build (push) Successful in 5m2s

- Integrate config ID type fixes (TEXT → UUID)
- Integrate connected_accounts, session_account_associations, account_sync_items
- Integrate bot hierarchy (parent_bot_id, enabled_tabs_json, inherit_parent_config)
- Integrate email_monitors, folder_monitors, folder_change_events, email_received_events
- Integrate user_organizations table
- Remove separate 6.1.1, 6.1.2, 6.1.3 migration folders
- Maximum version remains 6.1.0 per project standards
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2025-12-18 18:52:52 -03:00
parent ff6f332763
commit 26d7dcceb7
8 changed files with 491 additions and 467 deletions

View file

@ -1,6 +1,181 @@
-- Rollback Migration: 6.1.0 Enterprise Features
-- WARNING: This will delete all enterprise feature data!
-- NOTE: TABLES AND INDEXES ONLY - No views, triggers, or functions per project standards
-- Includes rollback for: config ID fixes, connected accounts, bot hierarchy, monitors
-- ============================================================================
-- ROLLBACK: Bot Hierarchy and Monitors (from 6.1.3)
-- ============================================================================
-- Drop comments first
COMMENT ON TABLE public.user_organizations IS NULL;
COMMENT ON TABLE public.email_received_events IS NULL;
COMMENT ON TABLE public.folder_change_events IS NULL;
COMMENT ON TABLE public.folder_monitors IS NULL;
COMMENT ON TABLE public.email_monitors IS NULL;
COMMENT ON COLUMN public.bots.inherit_parent_config IS NULL;
COMMENT ON COLUMN public.bots.enabled_tabs_json IS NULL;
COMMENT ON COLUMN public.bots.parent_bot_id IS NULL;
COMMENT ON TABLE public.system_automations IS NULL;
-- Drop user organizations table
DROP INDEX IF EXISTS idx_user_orgs_default;
DROP INDEX IF EXISTS idx_user_orgs_org;
DROP INDEX IF EXISTS idx_user_orgs_user;
DROP TABLE IF EXISTS public.user_organizations;
-- Drop email received events table
DROP INDEX IF EXISTS idx_email_events_received;
DROP INDEX IF EXISTS idx_email_events_processed;
DROP INDEX IF EXISTS idx_email_events_monitor;
DROP TABLE IF EXISTS public.email_received_events;
-- Drop folder change events table
DROP INDEX IF EXISTS idx_folder_events_created;
DROP INDEX IF EXISTS idx_folder_events_processed;
DROP INDEX IF EXISTS idx_folder_events_monitor;
DROP TABLE IF EXISTS public.folder_change_events;
-- Drop folder monitors table
DROP INDEX IF EXISTS idx_folder_monitors_account_email;
DROP INDEX IF EXISTS idx_folder_monitors_active;
DROP INDEX IF EXISTS idx_folder_monitors_provider;
DROP INDEX IF EXISTS idx_folder_monitors_bot_id;
DROP TABLE IF EXISTS public.folder_monitors;
-- Drop email monitors table
DROP INDEX IF EXISTS idx_email_monitors_active;
DROP INDEX IF EXISTS idx_email_monitors_email;
DROP INDEX IF EXISTS idx_email_monitors_bot_id;
DROP TABLE IF EXISTS public.email_monitors;
-- Remove bot hierarchy columns
DROP INDEX IF EXISTS idx_bots_parent_bot_id;
ALTER TABLE public.bots DROP COLUMN IF EXISTS inherit_parent_config;
ALTER TABLE public.bots DROP COLUMN IF EXISTS enabled_tabs_json;
ALTER TABLE public.bots DROP COLUMN IF EXISTS parent_bot_id;
-- ============================================================================
-- ROLLBACK: Connected Accounts (from 6.1.2)
-- ============================================================================
DROP INDEX IF EXISTS idx_account_sync_items_unique;
DROP INDEX IF EXISTS idx_account_sync_items_embedding;
DROP INDEX IF EXISTS idx_account_sync_items_date;
DROP INDEX IF EXISTS idx_account_sync_items_type;
DROP INDEX IF EXISTS idx_account_sync_items_account;
DROP TABLE IF EXISTS account_sync_items;
DROP INDEX IF EXISTS idx_session_account_assoc_unique;
DROP INDEX IF EXISTS idx_session_account_assoc_active;
DROP INDEX IF EXISTS idx_session_account_assoc_account;
DROP INDEX IF EXISTS idx_session_account_assoc_session;
DROP TABLE IF EXISTS session_account_associations;
DROP INDEX IF EXISTS idx_connected_accounts_bot_email;
DROP INDEX IF EXISTS idx_connected_accounts_status;
DROP INDEX IF EXISTS idx_connected_accounts_provider;
DROP INDEX IF EXISTS idx_connected_accounts_email;
DROP INDEX IF EXISTS idx_connected_accounts_user_id;
DROP INDEX IF EXISTS idx_connected_accounts_bot_id;
DROP TABLE IF EXISTS connected_accounts;
-- ============================================================================
-- ROLLBACK: Config ID Type Fixes (from 6.1.1)
-- Revert UUID columns back to TEXT
-- ============================================================================
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'bot_configuration'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE bot_configuration
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'server_configuration'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE server_configuration
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'tenant_configuration'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE tenant_configuration
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'model_configurations'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE model_configurations
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'connection_configurations'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE connection_configurations
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_installations'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE component_installations
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_logs'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE component_logs
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'gbot_config_sync'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE gbot_config_sync
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- ============================================================================
-- ROLLBACK: Original 6.1.0 Enterprise Features
-- ============================================================================
-- Drop test support tables
DROP TABLE IF EXISTS test_execution_logs;

View file

@ -1726,3 +1726,319 @@ CREATE TRIGGER external_connections_updated_at_trigger
BEFORE UPDATE ON external_connections
FOR EACH ROW
EXECUTE FUNCTION update_external_connections_updated_at();
-- ============================================================================
-- CONFIG ID TYPE FIXES (from 6.1.1)
-- Fix columns that were created as TEXT but should be UUID
-- ============================================================================
-- For bot_configuration
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'bot_configuration'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE bot_configuration
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- For server_configuration
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'server_configuration'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE server_configuration
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- For tenant_configuration
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'tenant_configuration'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE tenant_configuration
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- For model_configurations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'model_configurations'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE model_configurations
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- For connection_configurations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'connection_configurations'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE connection_configurations
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- For component_installations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_installations'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE component_installations
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- For component_logs
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_logs'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE component_logs
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- For gbot_config_sync
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'gbot_config_sync'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE gbot_config_sync
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- ============================================================================
-- CONNECTED ACCOUNTS (from 6.1.2)
-- OAuth connected accounts for email providers
-- ============================================================================
CREATE TABLE IF NOT EXISTS connected_accounts (
id UUID PRIMARY KEY,
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
user_id UUID,
email TEXT NOT NULL,
provider TEXT NOT NULL,
account_type TEXT NOT NULL DEFAULT 'email',
access_token TEXT NOT NULL,
refresh_token TEXT,
token_expires_at TIMESTAMPTZ,
scopes TEXT,
status TEXT NOT NULL DEFAULT 'active',
sync_enabled BOOLEAN NOT NULL DEFAULT true,
sync_interval_seconds INTEGER NOT NULL DEFAULT 300,
last_sync_at TIMESTAMPTZ,
last_sync_status TEXT,
last_sync_error TEXT,
metadata_json TEXT DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_bot_id ON connected_accounts(bot_id);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_user_id ON connected_accounts(user_id);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_email ON connected_accounts(email);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_provider ON connected_accounts(provider);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_status ON connected_accounts(status);
CREATE UNIQUE INDEX IF NOT EXISTS idx_connected_accounts_bot_email ON connected_accounts(bot_id, email);
CREATE TABLE IF NOT EXISTS session_account_associations (
id UUID PRIMARY KEY,
session_id UUID NOT NULL,
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
account_id UUID NOT NULL REFERENCES connected_accounts(id) ON DELETE CASCADE,
email TEXT NOT NULL,
provider TEXT NOT NULL,
qdrant_collection TEXT NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT true,
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
added_by_tool TEXT
);
CREATE INDEX IF NOT EXISTS idx_session_account_assoc_session ON session_account_associations(session_id);
CREATE INDEX IF NOT EXISTS idx_session_account_assoc_account ON session_account_associations(account_id);
CREATE INDEX IF NOT EXISTS idx_session_account_assoc_active ON session_account_associations(session_id, is_active);
CREATE UNIQUE INDEX IF NOT EXISTS idx_session_account_assoc_unique ON session_account_associations(session_id, account_id);
CREATE TABLE IF NOT EXISTS account_sync_items (
id UUID PRIMARY KEY,
account_id UUID NOT NULL REFERENCES connected_accounts(id) ON DELETE CASCADE,
item_type TEXT NOT NULL,
item_id TEXT NOT NULL,
subject TEXT,
content_preview TEXT,
sender TEXT,
recipients TEXT,
item_date TIMESTAMPTZ,
folder TEXT,
labels TEXT,
has_attachments BOOLEAN DEFAULT false,
qdrant_point_id TEXT,
embedding_status TEXT DEFAULT 'pending',
metadata_json TEXT DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_account ON account_sync_items(account_id);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_type ON account_sync_items(item_type);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_date ON account_sync_items(item_date);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_embedding ON account_sync_items(embedding_status);
CREATE UNIQUE INDEX IF NOT EXISTS idx_account_sync_items_unique ON account_sync_items(account_id, item_type, item_id);
-- ============================================================================
-- BOT HIERARCHY AND MONITORS (from 6.1.3)
-- Sub-bots, ON EMAIL triggers, ON CHANGE triggers
-- ============================================================================
-- Bot Hierarchy: Add parent_bot_id to support sub-bots
ALTER TABLE public.bots
ADD COLUMN IF NOT EXISTS parent_bot_id UUID REFERENCES public.bots(id) ON DELETE SET NULL;
-- Index for efficient hierarchy queries
CREATE INDEX IF NOT EXISTS idx_bots_parent_bot_id ON public.bots(parent_bot_id);
-- Bot enabled tabs configuration (which UI tabs are enabled for this bot)
ALTER TABLE public.bots
ADD COLUMN IF NOT EXISTS enabled_tabs_json TEXT DEFAULT '["chat"]';
-- Bot configuration inheritance flag
ALTER TABLE public.bots
ADD COLUMN IF NOT EXISTS inherit_parent_config BOOLEAN DEFAULT true;
-- Email monitoring table for ON EMAIL triggers
CREATE TABLE IF NOT EXISTS public.email_monitors (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL REFERENCES public.bots(id) ON DELETE CASCADE,
email_address VARCHAR(500) NOT NULL,
script_path VARCHAR(1000) NOT NULL,
is_active BOOLEAN DEFAULT true,
last_check_at TIMESTAMPTZ,
last_uid BIGINT DEFAULT 0,
filter_from VARCHAR(500),
filter_subject VARCHAR(500),
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
CONSTRAINT unique_bot_email UNIQUE (bot_id, email_address)
);
CREATE INDEX IF NOT EXISTS idx_email_monitors_bot_id ON public.email_monitors(bot_id);
CREATE INDEX IF NOT EXISTS idx_email_monitors_email ON public.email_monitors(email_address);
CREATE INDEX IF NOT EXISTS idx_email_monitors_active ON public.email_monitors(is_active) WHERE is_active = true;
-- Folder monitoring table for ON CHANGE triggers (GDrive, OneDrive, Dropbox)
-- Uses account:// syntax: account://user@gmail.com/path or gdrive:///path
CREATE TABLE IF NOT EXISTS public.folder_monitors (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL REFERENCES public.bots(id) ON DELETE CASCADE,
provider VARCHAR(50) NOT NULL, -- 'gdrive', 'onedrive', 'dropbox', 'local'
account_email VARCHAR(500), -- Email from account:// path (e.g., user@gmail.com)
folder_path VARCHAR(2000) NOT NULL,
folder_id VARCHAR(500), -- Provider-specific folder ID
script_path VARCHAR(1000) NOT NULL,
is_active BOOLEAN DEFAULT true,
watch_subfolders BOOLEAN DEFAULT true,
last_check_at TIMESTAMPTZ,
last_change_token VARCHAR(500), -- Provider-specific change token/page token
event_types_json TEXT DEFAULT '["create", "modify", "delete"]',
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
CONSTRAINT unique_bot_folder UNIQUE (bot_id, provider, folder_path)
);
CREATE INDEX IF NOT EXISTS idx_folder_monitors_bot_id ON public.folder_monitors(bot_id);
CREATE INDEX IF NOT EXISTS idx_folder_monitors_provider ON public.folder_monitors(provider);
CREATE INDEX IF NOT EXISTS idx_folder_monitors_active ON public.folder_monitors(is_active) WHERE is_active = true;
CREATE INDEX IF NOT EXISTS idx_folder_monitors_account_email ON public.folder_monitors(account_email);
-- Folder change events log
CREATE TABLE IF NOT EXISTS public.folder_change_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
monitor_id UUID NOT NULL REFERENCES public.folder_monitors(id) ON DELETE CASCADE,
event_type VARCHAR(50) NOT NULL, -- 'create', 'modify', 'delete', 'rename', 'move'
file_path VARCHAR(2000) NOT NULL,
file_id VARCHAR(500),
file_name VARCHAR(500),
file_size BIGINT,
mime_type VARCHAR(255),
old_path VARCHAR(2000), -- For rename/move events
processed BOOLEAN DEFAULT false,
processed_at TIMESTAMPTZ,
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_folder_events_monitor ON public.folder_change_events(monitor_id);
CREATE INDEX IF NOT EXISTS idx_folder_events_processed ON public.folder_change_events(processed) WHERE processed = false;
CREATE INDEX IF NOT EXISTS idx_folder_events_created ON public.folder_change_events(created_at);
-- Email received events log
CREATE TABLE IF NOT EXISTS public.email_received_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
monitor_id UUID NOT NULL REFERENCES public.email_monitors(id) ON DELETE CASCADE,
message_uid BIGINT NOT NULL,
message_id VARCHAR(500),
from_address VARCHAR(500) NOT NULL,
to_addresses_json TEXT,
subject VARCHAR(1000),
received_at TIMESTAMPTZ,
has_attachments BOOLEAN DEFAULT false,
attachments_json TEXT,
processed BOOLEAN DEFAULT false,
processed_at TIMESTAMPTZ,
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_email_events_monitor ON public.email_received_events(monitor_id);
CREATE INDEX IF NOT EXISTS idx_email_events_processed ON public.email_received_events(processed) WHERE processed = false;
CREATE INDEX IF NOT EXISTS idx_email_events_received ON public.email_received_events(received_at);
-- Add new trigger kinds to system_automations
-- TriggerKind enum: 0=Scheduled, 1=TableUpdate, 2=TableInsert, 3=TableDelete, 4=Webhook, 5=EmailReceived, 6=FolderChange
COMMENT ON TABLE public.system_automations IS 'System automations with TriggerKind: 0=Scheduled, 1=TableUpdate, 2=TableInsert, 3=TableDelete, 4=Webhook, 5=EmailReceived, 6=FolderChange';
-- User organization memberships (users can belong to multiple orgs)
CREATE TABLE IF NOT EXISTS public.user_organizations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES public.users(user_id) ON DELETE CASCADE,
org_id UUID NOT NULL REFERENCES public.organizations(org_id) ON DELETE CASCADE,
role VARCHAR(50) DEFAULT 'member', -- 'owner', 'admin', 'member', 'viewer'
is_default BOOLEAN DEFAULT false,
joined_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
CONSTRAINT unique_user_org UNIQUE (user_id, org_id)
);
CREATE INDEX IF NOT EXISTS idx_user_orgs_user ON public.user_organizations(user_id);
CREATE INDEX IF NOT EXISTS idx_user_orgs_org ON public.user_organizations(org_id);
CREATE INDEX IF NOT EXISTS idx_user_orgs_default ON public.user_organizations(user_id, is_default) WHERE is_default = true;
-- Comments for documentation
COMMENT ON COLUMN public.bots.parent_bot_id IS 'Parent bot ID for hierarchical bot structure. NULL means root bot.';
COMMENT ON COLUMN public.bots.enabled_tabs_json IS 'JSON array of enabled UI tabs for this bot. Root bots have all tabs.';
COMMENT ON COLUMN public.bots.inherit_parent_config IS 'If true, inherits config from parent bot for missing values.';
COMMENT ON TABLE public.email_monitors IS 'Email monitoring configuration for ON EMAIL triggers.';
COMMENT ON TABLE public.folder_monitors IS 'Folder monitoring configuration for ON CHANGE triggers (GDrive, OneDrive, Dropbox).';
COMMENT ON TABLE public.folder_change_events IS 'Log of detected folder changes to be processed by scripts.';
COMMENT ON TABLE public.email_received_events IS 'Log of received emails to be processed by scripts.';
COMMENT ON TABLE public.user_organizations IS 'User membership in organizations with roles.';

View file

@ -1,98 +0,0 @@
-- Rollback Migration 6.1.1: Revert UUID columns back to TEXT
-- This reverts the id columns from UUID back to TEXT
-- For bot_configuration
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'bot_configuration'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE bot_configuration
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- For server_configuration
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'server_configuration'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE server_configuration
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- For tenant_configuration
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'tenant_configuration'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE tenant_configuration
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- For model_configurations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'model_configurations'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE model_configurations
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- For connection_configurations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'connection_configurations'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE connection_configurations
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- For component_installations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_installations'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE component_installations
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- For component_logs
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_logs'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE component_logs
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;
-- For gbot_config_sync
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'gbot_config_sync'
AND column_name = 'id'
AND data_type = 'uuid') THEN
ALTER TABLE gbot_config_sync
ALTER COLUMN id TYPE TEXT USING id::text;
END IF;
END $$;

View file

@ -1,99 +0,0 @@
-- Migration 6.1.1: Fix bot_configuration id column type
-- The Diesel schema expects UUID but migration 6.0.4 created it as TEXT
-- This migration converts the id column from TEXT to UUID
-- For bot_configuration (main table that needs fixing)
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'bot_configuration'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE bot_configuration
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- Also fix server_configuration which has the same issue
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'server_configuration'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE server_configuration
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- Also fix tenant_configuration which has the same issue
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'tenant_configuration'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE tenant_configuration
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- Fix model_configurations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'model_configurations'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE model_configurations
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- Fix connection_configurations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'connection_configurations'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE connection_configurations
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- Fix component_installations
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_installations'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE component_installations
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- Fix component_logs
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'component_logs'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE component_logs
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;
-- Fix gbot_config_sync
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'gbot_config_sync'
AND column_name = 'id'
AND data_type = 'text') THEN
ALTER TABLE gbot_config_sync
ALTER COLUMN id TYPE UUID USING id::uuid;
END IF;
END $$;

View file

@ -1,20 +0,0 @@
DROP INDEX IF EXISTS idx_account_sync_items_unique;
DROP INDEX IF EXISTS idx_account_sync_items_embedding;
DROP INDEX IF EXISTS idx_account_sync_items_date;
DROP INDEX IF EXISTS idx_account_sync_items_type;
DROP INDEX IF EXISTS idx_account_sync_items_account;
DROP TABLE IF EXISTS account_sync_items;
DROP INDEX IF EXISTS idx_session_account_assoc_unique;
DROP INDEX IF EXISTS idx_session_account_assoc_active;
DROP INDEX IF EXISTS idx_session_account_assoc_account;
DROP INDEX IF EXISTS idx_session_account_assoc_session;
DROP TABLE IF EXISTS session_account_associations;
DROP INDEX IF EXISTS idx_connected_accounts_bot_email;
DROP INDEX IF EXISTS idx_connected_accounts_status;
DROP INDEX IF EXISTS idx_connected_accounts_provider;
DROP INDEX IF EXISTS idx_connected_accounts_email;
DROP INDEX IF EXISTS idx_connected_accounts_user_id;
DROP INDEX IF EXISTS idx_connected_accounts_bot_id;
DROP TABLE IF EXISTS connected_accounts;

View file

@ -1,72 +0,0 @@
CREATE TABLE IF NOT EXISTS connected_accounts (
id UUID PRIMARY KEY,
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
user_id UUID,
email TEXT NOT NULL,
provider TEXT NOT NULL,
account_type TEXT NOT NULL DEFAULT 'email',
access_token TEXT NOT NULL,
refresh_token TEXT,
token_expires_at TIMESTAMPTZ,
scopes TEXT,
status TEXT NOT NULL DEFAULT 'active',
sync_enabled BOOLEAN NOT NULL DEFAULT true,
sync_interval_seconds INTEGER NOT NULL DEFAULT 300,
last_sync_at TIMESTAMPTZ,
last_sync_status TEXT,
last_sync_error TEXT,
metadata_json TEXT DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_bot_id ON connected_accounts(bot_id);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_user_id ON connected_accounts(user_id);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_email ON connected_accounts(email);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_provider ON connected_accounts(provider);
CREATE INDEX IF NOT EXISTS idx_connected_accounts_status ON connected_accounts(status);
CREATE UNIQUE INDEX IF NOT EXISTS idx_connected_accounts_bot_email ON connected_accounts(bot_id, email);
CREATE TABLE IF NOT EXISTS session_account_associations (
id UUID PRIMARY KEY,
session_id UUID NOT NULL,
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
account_id UUID NOT NULL REFERENCES connected_accounts(id) ON DELETE CASCADE,
email TEXT NOT NULL,
provider TEXT NOT NULL,
qdrant_collection TEXT NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT true,
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
added_by_tool TEXT
);
CREATE INDEX IF NOT EXISTS idx_session_account_assoc_session ON session_account_associations(session_id);
CREATE INDEX IF NOT EXISTS idx_session_account_assoc_account ON session_account_associations(account_id);
CREATE INDEX IF NOT EXISTS idx_session_account_assoc_active ON session_account_associations(session_id, is_active);
CREATE UNIQUE INDEX IF NOT EXISTS idx_session_account_assoc_unique ON session_account_associations(session_id, account_id);
CREATE TABLE IF NOT EXISTS account_sync_items (
id UUID PRIMARY KEY,
account_id UUID NOT NULL REFERENCES connected_accounts(id) ON DELETE CASCADE,
item_type TEXT NOT NULL,
item_id TEXT NOT NULL,
subject TEXT,
content_preview TEXT,
sender TEXT,
recipients TEXT,
item_date TIMESTAMPTZ,
folder TEXT,
labels TEXT,
has_attachments BOOLEAN DEFAULT false,
qdrant_point_id TEXT,
embedding_status TEXT DEFAULT 'pending',
metadata_json TEXT DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_account ON account_sync_items(account_id);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_type ON account_sync_items(item_type);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_date ON account_sync_items(item_date);
CREATE INDEX IF NOT EXISTS idx_account_sync_items_embedding ON account_sync_items(embedding_status);
CREATE UNIQUE INDEX IF NOT EXISTS idx_account_sync_items_unique ON account_sync_items(account_id, item_type, item_id);

View file

@ -1,47 +0,0 @@
-- Drop comments first
COMMENT ON TABLE public.user_organizations IS NULL;
COMMENT ON TABLE public.email_received_events IS NULL;
COMMENT ON TABLE public.folder_change_events IS NULL;
COMMENT ON TABLE public.folder_monitors IS NULL;
COMMENT ON TABLE public.email_monitors IS NULL;
COMMENT ON COLUMN public.bots.inherit_parent_config IS NULL;
COMMENT ON COLUMN public.bots.enabled_tabs_json IS NULL;
COMMENT ON COLUMN public.bots.parent_bot_id IS NULL;
COMMENT ON TABLE public.system_automations IS NULL;
-- Drop user organizations table
DROP INDEX IF EXISTS idx_user_orgs_default;
DROP INDEX IF EXISTS idx_user_orgs_org;
DROP INDEX IF EXISTS idx_user_orgs_user;
DROP TABLE IF EXISTS public.user_organizations;
-- Drop email received events table
DROP INDEX IF EXISTS idx_email_events_received;
DROP INDEX IF EXISTS idx_email_events_processed;
DROP INDEX IF EXISTS idx_email_events_monitor;
DROP TABLE IF EXISTS public.email_received_events;
-- Drop folder change events table
DROP INDEX IF EXISTS idx_folder_events_created;
DROP INDEX IF EXISTS idx_folder_events_processed;
DROP INDEX IF EXISTS idx_folder_events_monitor;
DROP TABLE IF EXISTS public.folder_change_events;
-- Drop folder monitors table
DROP INDEX IF EXISTS idx_folder_monitors_account_email;
DROP INDEX IF EXISTS idx_folder_monitors_active;
DROP INDEX IF EXISTS idx_folder_monitors_provider;
DROP INDEX IF EXISTS idx_folder_monitors_bot_id;
DROP TABLE IF EXISTS public.folder_monitors;
-- Drop email monitors table
DROP INDEX IF EXISTS idx_email_monitors_active;
DROP INDEX IF EXISTS idx_email_monitors_email;
DROP INDEX IF EXISTS idx_email_monitors_bot_id;
DROP TABLE IF EXISTS public.email_monitors;
-- Remove bot hierarchy columns
DROP INDEX IF EXISTS idx_bots_parent_bot_id;
ALTER TABLE public.bots DROP COLUMN IF EXISTS inherit_parent_config;
ALTER TABLE public.bots DROP COLUMN IF EXISTS enabled_tabs_json;
ALTER TABLE public.bots DROP COLUMN IF EXISTS parent_bot_id;

View file

@ -1,131 +0,0 @@
-- Bot Hierarchy: Add parent_bot_id to support sub-bots
ALTER TABLE public.bots
ADD COLUMN IF NOT EXISTS parent_bot_id UUID REFERENCES public.bots(id) ON DELETE SET NULL;
-- Index for efficient hierarchy queries
CREATE INDEX IF NOT EXISTS idx_bots_parent_bot_id ON public.bots(parent_bot_id);
-- Bot enabled tabs configuration (which UI tabs are enabled for this bot)
ALTER TABLE public.bots
ADD COLUMN IF NOT EXISTS enabled_tabs_json TEXT DEFAULT '["chat"]';
-- Bot configuration inheritance flag
ALTER TABLE public.bots
ADD COLUMN IF NOT EXISTS inherit_parent_config BOOLEAN DEFAULT true;
-- Email monitoring table for ON EMAIL triggers
CREATE TABLE IF NOT EXISTS public.email_monitors (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL REFERENCES public.bots(id) ON DELETE CASCADE,
email_address VARCHAR(500) NOT NULL,
script_path VARCHAR(1000) NOT NULL,
is_active BOOLEAN DEFAULT true,
last_check_at TIMESTAMPTZ,
last_uid BIGINT DEFAULT 0,
filter_from VARCHAR(500),
filter_subject VARCHAR(500),
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
CONSTRAINT unique_bot_email UNIQUE (bot_id, email_address)
);
CREATE INDEX IF NOT EXISTS idx_email_monitors_bot_id ON public.email_monitors(bot_id);
CREATE INDEX IF NOT EXISTS idx_email_monitors_email ON public.email_monitors(email_address);
CREATE INDEX IF NOT EXISTS idx_email_monitors_active ON public.email_monitors(is_active) WHERE is_active = true;
-- Folder monitoring table for ON CHANGE triggers (GDrive, OneDrive, Dropbox)
-- Uses account:// syntax: account://user@gmail.com/path or gdrive:///path
CREATE TABLE IF NOT EXISTS public.folder_monitors (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL REFERENCES public.bots(id) ON DELETE CASCADE,
provider VARCHAR(50) NOT NULL, -- 'gdrive', 'onedrive', 'dropbox', 'local'
account_email VARCHAR(500), -- Email from account:// path (e.g., user@gmail.com)
folder_path VARCHAR(2000) NOT NULL,
folder_id VARCHAR(500), -- Provider-specific folder ID
script_path VARCHAR(1000) NOT NULL,
is_active BOOLEAN DEFAULT true,
watch_subfolders BOOLEAN DEFAULT true,
last_check_at TIMESTAMPTZ,
last_change_token VARCHAR(500), -- Provider-specific change token/page token
event_types_json TEXT DEFAULT '["create", "modify", "delete"]',
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
CONSTRAINT unique_bot_folder UNIQUE (bot_id, provider, folder_path)
);
CREATE INDEX IF NOT EXISTS idx_folder_monitors_bot_id ON public.folder_monitors(bot_id);
CREATE INDEX IF NOT EXISTS idx_folder_monitors_provider ON public.folder_monitors(provider);
CREATE INDEX IF NOT EXISTS idx_folder_monitors_active ON public.folder_monitors(is_active) WHERE is_active = true;
CREATE INDEX IF NOT EXISTS idx_folder_monitors_account_email ON public.folder_monitors(account_email);
-- Folder change events log
CREATE TABLE IF NOT EXISTS public.folder_change_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
monitor_id UUID NOT NULL REFERENCES public.folder_monitors(id) ON DELETE CASCADE,
event_type VARCHAR(50) NOT NULL, -- 'create', 'modify', 'delete', 'rename', 'move'
file_path VARCHAR(2000) NOT NULL,
file_id VARCHAR(500),
file_name VARCHAR(500),
file_size BIGINT,
mime_type VARCHAR(255),
old_path VARCHAR(2000), -- For rename/move events
processed BOOLEAN DEFAULT false,
processed_at TIMESTAMPTZ,
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_folder_events_monitor ON public.folder_change_events(monitor_id);
CREATE INDEX IF NOT EXISTS idx_folder_events_processed ON public.folder_change_events(processed) WHERE processed = false;
CREATE INDEX IF NOT EXISTS idx_folder_events_created ON public.folder_change_events(created_at);
-- Email received events log
CREATE TABLE IF NOT EXISTS public.email_received_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
monitor_id UUID NOT NULL REFERENCES public.email_monitors(id) ON DELETE CASCADE,
message_uid BIGINT NOT NULL,
message_id VARCHAR(500),
from_address VARCHAR(500) NOT NULL,
to_addresses_json TEXT,
subject VARCHAR(1000),
received_at TIMESTAMPTZ,
has_attachments BOOLEAN DEFAULT false,
attachments_json TEXT,
processed BOOLEAN DEFAULT false,
processed_at TIMESTAMPTZ,
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_email_events_monitor ON public.email_received_events(monitor_id);
CREATE INDEX IF NOT EXISTS idx_email_events_processed ON public.email_received_events(processed) WHERE processed = false;
CREATE INDEX IF NOT EXISTS idx_email_events_received ON public.email_received_events(received_at);
-- Add new trigger kinds to system_automations
-- TriggerKind enum: 0=Scheduled, 1=TableUpdate, 2=TableInsert, 3=TableDelete, 4=Webhook, 5=EmailReceived, 6=FolderChange
COMMENT ON TABLE public.system_automations IS 'System automations with TriggerKind: 0=Scheduled, 1=TableUpdate, 2=TableInsert, 3=TableDelete, 4=Webhook, 5=EmailReceived, 6=FolderChange';
-- User organization memberships (users can belong to multiple orgs)
CREATE TABLE IF NOT EXISTS public.user_organizations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES public.users(user_id) ON DELETE CASCADE,
org_id UUID NOT NULL REFERENCES public.organizations(org_id) ON DELETE CASCADE,
role VARCHAR(50) DEFAULT 'member', -- 'owner', 'admin', 'member', 'viewer'
is_default BOOLEAN DEFAULT false,
joined_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
CONSTRAINT unique_user_org UNIQUE (user_id, org_id)
);
CREATE INDEX IF NOT EXISTS idx_user_orgs_user ON public.user_organizations(user_id);
CREATE INDEX IF NOT EXISTS idx_user_orgs_org ON public.user_organizations(org_id);
CREATE INDEX IF NOT EXISTS idx_user_orgs_default ON public.user_organizations(user_id, is_default) WHERE is_default = true;
-- Comments for documentation
COMMENT ON COLUMN public.bots.parent_bot_id IS 'Parent bot ID for hierarchical bot structure. NULL means root bot.';
COMMENT ON COLUMN public.bots.enabled_tabs_json IS 'JSON array of enabled UI tabs for this bot. Root bots have all tabs.';
COMMENT ON COLUMN public.bots.inherit_parent_config IS 'If true, inherits config from parent bot for missing values.';
COMMENT ON TABLE public.email_monitors IS 'Email monitoring configuration for ON EMAIL triggers.';
COMMENT ON TABLE public.folder_monitors IS 'Folder monitoring configuration for ON CHANGE triggers (GDrive, OneDrive, Dropbox).';
COMMENT ON TABLE public.folder_change_events IS 'Log of detected folder changes to be processed by scripts.';
COMMENT ON TABLE public.email_received_events IS 'Log of received emails to be processed by scripts.';
COMMENT ON TABLE public.user_organizations IS 'User membership in organizations with roles.';