michangarrito/database/schemas/12-integrations.sql
rckrdmrd 48dea7a5d0 feat: Initial commit - michangarrito
Marketplace móvil para negocios locales mexicanos.

Estructura inicial:
- apps/backend (NestJS API)
- apps/frontend (React Web)
- apps/mobile (Expo/React Native)
- apps/mcp-server (Claude MCP Server)
- apps/whatsapp-service (WhatsApp Business API)
- database/ (PostgreSQL DDL)
- docs/ (Documentación)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:41:02 -06:00

146 lines
5.0 KiB
SQL

-- =============================================================================
-- MICHANGARRITO - 12 INTEGRATIONS (Multi-tenant Credentials)
-- =============================================================================
-- Credenciales de integraciones externas por tenant
-- Soporta: WhatsApp, LLM (OpenAI, OpenRouter, Anthropic), Stripe, etc.
-- =============================================================================
-- Tipo de integración
CREATE TYPE integration_type AS ENUM (
'whatsapp',
'llm',
'stripe',
'mercadopago',
'clip'
);
-- Proveedor de integración
CREATE TYPE integration_provider AS ENUM (
-- WhatsApp
'meta',
-- LLM
'openai',
'openrouter',
'anthropic',
'ollama',
'azure_openai',
-- Payments
'stripe',
'mercadopago',
'clip'
);
-- Tabla de credenciales de integración por tenant
CREATE TABLE IF NOT EXISTS public.tenant_integration_credentials (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
-- Tipo y proveedor
integration_type integration_type NOT NULL,
provider integration_provider NOT NULL,
-- Credenciales (almacenadas como JSON para flexibilidad)
-- En producción considerar encriptación con pgcrypto
credentials JSONB NOT NULL DEFAULT '{}',
-- Configuración adicional
config JSONB DEFAULT '{}',
-- Estado
is_active BOOLEAN DEFAULT true,
is_verified BOOLEAN DEFAULT false,
last_verified_at TIMESTAMPTZ,
verification_error TEXT,
-- Auditoría
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
created_by UUID,
updated_by UUID,
-- Constraint: un tenant solo puede tener una config por tipo+proveedor
UNIQUE(tenant_id, integration_type, provider)
);
-- Índices para búsqueda rápida
CREATE INDEX idx_tenant_integrations_tenant ON public.tenant_integration_credentials(tenant_id);
CREATE INDEX idx_tenant_integrations_type ON public.tenant_integration_credentials(integration_type);
CREATE INDEX idx_tenant_integrations_active ON public.tenant_integration_credentials(tenant_id, is_active) WHERE is_active = true;
-- Trigger de updated_at
CREATE TRIGGER update_tenant_integration_credentials_updated_at
BEFORE UPDATE ON public.tenant_integration_credentials
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- Comentarios
COMMENT ON TABLE public.tenant_integration_credentials IS 'Credenciales de integraciones externas por tenant (WhatsApp, LLM, Pagos)';
COMMENT ON COLUMN public.tenant_integration_credentials.credentials IS 'JSON con credenciales: {access_token, api_key, phone_number_id, etc.}';
COMMENT ON COLUMN public.tenant_integration_credentials.config IS 'JSON con configuración: {model, temperature, max_tokens, etc.}';
-- =============================================================================
-- EJEMPLOS DE ESTRUCTURA DE CREDENTIALS Y CONFIG
-- =============================================================================
--
-- WhatsApp (Meta):
-- credentials: {
-- "access_token": "EAAxxxxx...",
-- "phone_number_id": "123456789",
-- "business_account_id": "987654321",
-- "verify_token": "my_verify_token"
-- }
-- config: {
-- "webhook_url": "https://michangarrito.com/webhook/whatsapp"
-- }
--
-- LLM (OpenAI):
-- credentials: {
-- "api_key": "sk-xxxxx..."
-- }
-- config: {
-- "model": "gpt-4o-mini",
-- "max_tokens": 1000,
-- "temperature": 0.7,
-- "system_prompt": "Eres un asistente de ventas..."
-- }
--
-- LLM (OpenRouter):
-- credentials: {
-- "api_key": "sk-or-xxxxx..."
-- }
-- config: {
-- "model": "anthropic/claude-3-haiku",
-- "max_tokens": 1000,
-- "base_url": "https://openrouter.ai/api/v1"
-- }
--
-- Stripe:
-- credentials: {
-- "secret_key": "sk_live_xxxxx",
-- "publishable_key": "pk_live_xxxxx",
-- "webhook_secret": "whsec_xxxxx"
-- }
-- =============================================================================
-- Agregar campos a tenants para configuración rápida de integración preferida
ALTER TABLE public.tenants
ADD COLUMN IF NOT EXISTS preferred_llm_provider integration_provider DEFAULT 'openai',
ADD COLUMN IF NOT EXISTS preferred_payment_provider integration_provider DEFAULT 'stripe';
-- Índice para buscar tenant por phone_number_id de WhatsApp (para webhooks)
CREATE TABLE IF NOT EXISTS public.tenant_whatsapp_numbers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
phone_number_id VARCHAR(50) NOT NULL UNIQUE,
phone_number VARCHAR(20),
display_name VARCHAR(100),
is_platform_number BOOLEAN DEFAULT false,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(tenant_id, phone_number_id)
);
CREATE INDEX idx_tenant_whatsapp_numbers_phone_id ON public.tenant_whatsapp_numbers(phone_number_id);
COMMENT ON TABLE public.tenant_whatsapp_numbers IS 'Mapeo de phone_number_id de WhatsApp a tenant (para resolver en webhooks)';