michangarrito-database-v2/schemas/onboarding.sql
rckrdmrd 9f51315ea1 [MCH-006] feat: Agregar schema SQL para onboarding inteligente
- Crear ENUMs: onboarding_status, onboarding_channel, scan_type, scan_status
- Crear tabla auth.onboarding_sessions para sesiones de configuracion
- Crear tabla catalog.product_scans para resultados OCR/audio
- Agregar indices para queries frecuentes
- Trigger para updated_at automatico

Sprint 5 - Modulo Onboarding Inteligente

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 04:19:48 -06:00

156 lines
4.3 KiB
PL/PgSQL

-- =====================================================
-- SCHEMA: Onboarding Inteligente
-- Epica: MCH-006 - Onboarding Inteligente
-- Fecha: 2026-01-18
-- =====================================================
-- ENUM: Onboarding Status
DO $$ BEGIN
CREATE TYPE onboarding_status AS ENUM (
'started',
'business_info',
'giro_selected',
'templates_loaded',
'products_added',
'completed',
'abandoned'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
-- ENUM: Onboarding Channel
DO $$ BEGIN
CREATE TYPE onboarding_channel AS ENUM (
'whatsapp',
'web',
'app'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
-- ENUM: Scan Type
DO $$ BEGIN
CREATE TYPE scan_type AS ENUM (
'photo',
'audio',
'barcode'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
-- ENUM: Scan Status
DO $$ BEGIN
CREATE TYPE scan_status AS ENUM (
'pending',
'processing',
'detected',
'confirmed',
'rejected',
'failed'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
-- TABLA: onboarding_sessions
CREATE TABLE IF NOT EXISTS auth.onboarding_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID REFERENCES auth.tenants(id) ON DELETE SET NULL,
phone_number VARCHAR(20) NOT NULL,
channel onboarding_channel DEFAULT 'whatsapp',
status onboarding_status DEFAULT 'started',
current_step INTEGER DEFAULT 1,
total_steps INTEGER DEFAULT 5,
-- Business info collected
business_name VARCHAR(100),
business_giro VARCHAR(50),
owner_name VARCHAR(100),
-- Progress tracking
templates_imported INTEGER DEFAULT 0,
products_added INTEGER DEFAULT 0,
photos_processed INTEGER DEFAULT 0,
audios_processed INTEGER DEFAULT 0,
-- Metadata
metadata JSONB,
last_message_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
started_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- INDICES para onboarding_sessions
CREATE INDEX IF NOT EXISTS idx_onboarding_sessions_tenant_status
ON auth.onboarding_sessions(tenant_id, status);
CREATE INDEX IF NOT EXISTS idx_onboarding_sessions_phone
ON auth.onboarding_sessions(phone_number);
CREATE INDEX IF NOT EXISTS idx_onboarding_sessions_status
ON auth.onboarding_sessions(status) WHERE status != 'completed';
-- TABLA: product_scans
CREATE TABLE IF NOT EXISTS catalog.product_scans (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES auth.onboarding_sessions(id) ON DELETE CASCADE,
tenant_id UUID REFERENCES auth.tenants(id) ON DELETE SET NULL,
type scan_type NOT NULL,
status scan_status DEFAULT 'pending',
-- Input data
media_url TEXT,
media_mime_type VARCHAR(50),
raw_text TEXT,
-- OCR/Transcription results
detected_name VARCHAR(150),
detected_price DECIMAL(10,2),
detected_barcode VARCHAR(50),
confidence_score DECIMAL(3,2),
-- Matched template
template_id UUID REFERENCES catalog.product_templates(id) ON DELETE SET NULL,
template_match_score DECIMAL(3,2),
-- Final product created
product_id UUID REFERENCES catalog.products(id) ON DELETE SET NULL,
-- User corrections
user_confirmed_name VARCHAR(150),
user_confirmed_price DECIMAL(10,2),
-- Metadata
metadata JSONB,
error_message TEXT,
processing_time_ms INTEGER,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- INDICES para product_scans
CREATE INDEX IF NOT EXISTS idx_product_scans_session_status
ON catalog.product_scans(session_id, status);
CREATE INDEX IF NOT EXISTS idx_product_scans_template
ON catalog.product_scans(template_id) WHERE template_id IS NOT NULL;
-- TRIGGER: Actualizar updated_at en onboarding_sessions
CREATE OR REPLACE FUNCTION update_onboarding_sessions_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_onboarding_sessions_updated_at ON auth.onboarding_sessions;
CREATE TRIGGER trg_onboarding_sessions_updated_at
BEFORE UPDATE ON auth.onboarding_sessions
FOR EACH ROW
EXECUTE FUNCTION update_onboarding_sessions_updated_at();
-- =====================================================
-- FIN DEL SCHEMA
-- =====================================================