feat: WhatsApp Nucleo con Nuxt 4 + Baileys v7
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m46s
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 6m46s
Reemplazo completo de Evolution API por implementación directa con Baileys. Características: - Dashboard completo con Nuxt UI v4 - Soporte para múltiples instancias de WhatsApp - Conexión via QR code o pairing code - Persistencia de mensajes en PostgreSQL - API REST para integraciones externas - Webhooks con firma HMAC - SSE para actualizaciones en tiempo real - Autenticación con Authentik
This commit is contained in:
208
server/database/init/001_schema.sql
Normal file
208
server/database/init/001_schema.sql
Normal file
@@ -0,0 +1,208 @@
|
||||
-- =====================================================
|
||||
-- WhatsApp Nucleo - Database Schema
|
||||
-- =====================================================
|
||||
|
||||
-- Extension for UUID generation
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
-- =====================================================
|
||||
-- INSTANCES: WhatsApp connection instances
|
||||
-- =====================================================
|
||||
CREATE TABLE instances (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
phone_number VARCHAR(20),
|
||||
status VARCHAR(20) DEFAULT 'disconnected'
|
||||
CHECK (status IN ('disconnected', 'connecting', 'connected', 'qr_ready', 'pairing')),
|
||||
qr_code TEXT,
|
||||
pairing_code VARCHAR(10),
|
||||
last_connected_at TIMESTAMPTZ,
|
||||
created_by VARCHAR(100) NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
CONSTRAINT unique_phone UNIQUE (phone_number)
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- AUTH_KEYS: Baileys credentials per instance
|
||||
-- =====================================================
|
||||
CREATE TABLE auth_keys (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
instance_id UUID NOT NULL REFERENCES instances(id) ON DELETE CASCADE,
|
||||
key_type VARCHAR(50) NOT NULL,
|
||||
key_id VARCHAR(100),
|
||||
key_data JSONB NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
CONSTRAINT unique_key UNIQUE (instance_id, key_type, key_id)
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- CONTACTS: WhatsApp contacts
|
||||
-- =====================================================
|
||||
CREATE TABLE contacts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
instance_id UUID NOT NULL REFERENCES instances(id) ON DELETE CASCADE,
|
||||
jid VARCHAR(100) NOT NULL,
|
||||
name VARCHAR(255),
|
||||
push_name VARCHAR(255),
|
||||
phone_number VARCHAR(20),
|
||||
profile_picture_url TEXT,
|
||||
is_group BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
CONSTRAINT unique_contact UNIQUE (instance_id, jid)
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- CHATS: Conversations
|
||||
-- =====================================================
|
||||
CREATE TABLE chats (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
instance_id UUID NOT NULL REFERENCES instances(id) ON DELETE CASCADE,
|
||||
jid VARCHAR(100) NOT NULL,
|
||||
name VARCHAR(255),
|
||||
is_group BOOLEAN DEFAULT FALSE,
|
||||
is_archived BOOLEAN DEFAULT FALSE,
|
||||
is_pinned BOOLEAN DEFAULT FALSE,
|
||||
unread_count INTEGER DEFAULT 0,
|
||||
last_message_id UUID,
|
||||
last_message_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
CONSTRAINT unique_chat UNIQUE (instance_id, jid)
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- MESSAGES: All messages
|
||||
-- =====================================================
|
||||
CREATE TABLE messages (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
instance_id UUID NOT NULL REFERENCES instances(id) ON DELETE CASCADE,
|
||||
chat_id UUID NOT NULL REFERENCES chats(id) ON DELETE CASCADE,
|
||||
message_id VARCHAR(100) NOT NULL,
|
||||
from_jid VARCHAR(100) NOT NULL,
|
||||
to_jid VARCHAR(100),
|
||||
from_me BOOLEAN DEFAULT FALSE,
|
||||
message_type VARCHAR(50) NOT NULL,
|
||||
content TEXT,
|
||||
caption TEXT,
|
||||
media_url TEXT,
|
||||
media_mimetype VARCHAR(100),
|
||||
media_filename VARCHAR(255),
|
||||
quoted_message_id VARCHAR(100),
|
||||
timestamp TIMESTAMPTZ NOT NULL,
|
||||
status VARCHAR(20) DEFAULT 'sent'
|
||||
CHECK (status IN ('pending', 'sent', 'delivered', 'read', 'failed')),
|
||||
raw_message JSONB,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
CONSTRAINT unique_message UNIQUE (instance_id, message_id)
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- WEBHOOKS: Webhook configurations
|
||||
-- =====================================================
|
||||
CREATE TABLE webhooks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
instance_id UUID REFERENCES instances(id) ON DELETE CASCADE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
secret VARCHAR(255),
|
||||
events TEXT[] NOT NULL DEFAULT '{}',
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
headers JSONB DEFAULT '{}',
|
||||
retry_count INTEGER DEFAULT 3,
|
||||
timeout_ms INTEGER DEFAULT 5000,
|
||||
created_by VARCHAR(100) NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- WEBHOOK_LOGS: Delivery logs
|
||||
-- =====================================================
|
||||
CREATE TABLE webhook_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
webhook_id UUID NOT NULL REFERENCES webhooks(id) ON DELETE CASCADE,
|
||||
event_type VARCHAR(50) NOT NULL,
|
||||
payload JSONB NOT NULL,
|
||||
response_status INTEGER,
|
||||
response_body TEXT,
|
||||
error_message TEXT,
|
||||
attempt INTEGER DEFAULT 1,
|
||||
delivered_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- API_KEYS: External API access keys
|
||||
-- =====================================================
|
||||
CREATE TABLE api_keys (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
key_hash VARCHAR(255) NOT NULL,
|
||||
key_prefix VARCHAR(10) NOT NULL,
|
||||
instance_id UUID REFERENCES instances(id) ON DELETE CASCADE,
|
||||
permissions TEXT[] NOT NULL DEFAULT '{}',
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
last_used_at TIMESTAMPTZ,
|
||||
expires_at TIMESTAMPTZ,
|
||||
created_by VARCHAR(100) NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- INDEXES for performance
|
||||
-- =====================================================
|
||||
CREATE INDEX idx_auth_keys_instance ON auth_keys(instance_id);
|
||||
CREATE INDEX idx_contacts_instance ON contacts(instance_id);
|
||||
CREATE INDEX idx_chats_instance ON chats(instance_id);
|
||||
CREATE INDEX idx_chats_last_message ON chats(instance_id, last_message_at DESC);
|
||||
CREATE INDEX idx_messages_instance_chat ON messages(instance_id, chat_id);
|
||||
CREATE INDEX idx_messages_timestamp ON messages(timestamp DESC);
|
||||
CREATE INDEX idx_messages_chat_timestamp ON messages(chat_id, timestamp DESC);
|
||||
CREATE INDEX idx_webhooks_instance ON webhooks(instance_id);
|
||||
CREATE INDEX idx_webhooks_active ON webhooks(is_active) WHERE is_active = TRUE;
|
||||
CREATE INDEX idx_webhook_logs_webhook ON webhook_logs(webhook_id, created_at DESC);
|
||||
CREATE INDEX idx_api_keys_prefix ON api_keys(key_prefix) WHERE is_active = TRUE;
|
||||
|
||||
-- =====================================================
|
||||
-- TRIGGERS for updated_at
|
||||
-- =====================================================
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
CREATE TRIGGER update_instances_updated_at
|
||||
BEFORE UPDATE ON instances
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_auth_keys_updated_at
|
||||
BEFORE UPDATE ON auth_keys
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_contacts_updated_at
|
||||
BEFORE UPDATE ON contacts
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_chats_updated_at
|
||||
BEFORE UPDATE ON chats
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_webhooks_updated_at
|
||||
BEFORE UPDATE ON webhooks
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
Reference in New Issue
Block a user