From 9f51315ea1cdd6567594dc59a2e42d4c230f7925 Mon Sep 17 00:00:00 2001 From: rckrdmrd Date: Sun, 18 Jan 2026 04:19:48 -0600 Subject: [PATCH] [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 --- schemas/onboarding.sql | 155 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 schemas/onboarding.sql diff --git a/schemas/onboarding.sql b/schemas/onboarding.sql new file mode 100644 index 0000000..db07286 --- /dev/null +++ b/schemas/onboarding.sql @@ -0,0 +1,155 @@ +-- ===================================================== +-- 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 +-- =====================================================