SET lock_timeout = '10s';
SET statement_timeout = '120000';

CREATE SCHEMA IF NOT EXISTS commerce;
CREATE SCHEMA IF NOT EXISTS crm;
CREATE SCHEMA IF NOT EXISTS ops;

CREATE TABLE IF NOT EXISTS commerce.cotizaciones (
    id_cotizacion BIGSERIAL PRIMARY KEY,
    business_id VARCHAR(100) NOT NULL,
    sucursal INT4[] NOT NULL,
    id_cliente INTEGER NOT NULL,
    id_modelo_plan_pago_contexto INTEGER,
    folio_cotizacion VARCHAR(120),
    fecha_cotizacion TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    vigencia_hasta TIMESTAMPTZ,
    currency_code VARCHAR(3) NOT NULL DEFAULT 'MXN',
    document_option_mode VARCHAR(24) NOT NULL DEFAULT 'pdf_only',
    estado_general VARCHAR(32) NOT NULL DEFAULT 'draft',
    preflight_status VARCHAR(32) NOT NULL DEFAULT 'pending',
    excel_status VARCHAR(32) NOT NULL DEFAULT 'pending',
    pdf_status VARCHAR(32) NOT NULL DEFAULT 'pending',
    preflight_job_id VARCHAR(255),
    excel_job_id VARCHAR(255),
    pdf_job_id VARCHAR(255),
    cotizacion_source_snapshot JSONB NOT NULL DEFAULT '{}'::jsonb,
    analysis_summary JSONB NOT NULL DEFAULT '{}'::jsonb,
    questions_decision JSONB NOT NULL DEFAULT '{}'::jsonb,
    questions_for_ui JSONB NOT NULL DEFAULT '[]'::jsonb,
    questionnaire_answers JSONB NOT NULL DEFAULT '[]'::jsonb,
    pricing_canonical_payload JSONB NOT NULL DEFAULT '{}'::jsonb,
    excel_canonical_payload JSONB NOT NULL DEFAULT '{}'::jsonb,
    pdf_render_payload JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by_login_id INTEGER NOT NULL,
    created_by_user_id INTEGER,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_by_login_id INTEGER,
    soft_delete BOOLEAN NOT NULL DEFAULT FALSE,
    soft_delete_date TIMESTAMPTZ,
    CONSTRAINT fk_cotizaciones_cliente
        FOREIGN KEY (id_cliente)
        REFERENCES crm.clientes (id_cliente)
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT fk_cotizaciones_modelo_contexto
        FOREIGN KEY (id_modelo_plan_pago_contexto)
        REFERENCES commerce.modelos_planes_pago (id_modelo)
        ON UPDATE CASCADE
        ON DELETE SET NULL,
    CONSTRAINT chk_cotizaciones_business_id_not_empty
        CHECK (length(trim(business_id)) > 0),
    CONSTRAINT chk_cotizaciones_sucursal_single_scope
        CHECK (cardinality(sucursal) = 1),
    CONSTRAINT chk_cotizaciones_sucursal_positive
        CHECK (sucursal[1] > 0),
    CONSTRAINT chk_cotizaciones_cliente_positive
        CHECK (id_cliente > 0),
    CONSTRAINT chk_cotizaciones_modelo_contexto_positive
        CHECK (id_modelo_plan_pago_contexto IS NULL OR id_modelo_plan_pago_contexto > 0),
    CONSTRAINT chk_cotizaciones_folio_not_empty
        CHECK (folio_cotizacion IS NULL OR length(trim(folio_cotizacion)) > 0),
    CONSTRAINT chk_cotizaciones_vigencia_coherente
        CHECK (vigencia_hasta IS NULL OR vigencia_hasta >= fecha_cotizacion),
    CONSTRAINT chk_cotizaciones_currency_code
        CHECK (NULLIF(btrim(currency_code), '') IS NOT NULL AND btrim(currency_code) ~ '^[A-Z]{3}$'),
    CONSTRAINT chk_cotizaciones_document_option_mode
        CHECK (document_option_mode IN ('pdf_only', 'pdf_and_excel')),
    CONSTRAINT chk_cotizaciones_estado_general
        CHECK (estado_general IN ('draft', 'preflight_processing', 'awaiting_answers', 'excel_processing', 'pdf_processing', 'completed', 'error')),
    CONSTRAINT chk_cotizaciones_preflight_status
        CHECK (preflight_status IN ('pending', 'processing', 'awaiting_answers', 'completed', 'error')),
    CONSTRAINT chk_cotizaciones_excel_status
        CHECK (excel_status IN ('pending', 'processing', 'completed', 'skipped', 'error')),
    CONSTRAINT chk_cotizaciones_pdf_status
        CHECK (pdf_status IN ('pending', 'processing', 'completed', 'error')),
    CONSTRAINT chk_cotizaciones_preflight_job_id_not_empty
        CHECK (preflight_job_id IS NULL OR length(trim(preflight_job_id)) > 0),
    CONSTRAINT chk_cotizaciones_excel_job_id_not_empty
        CHECK (excel_job_id IS NULL OR length(trim(excel_job_id)) > 0),
    CONSTRAINT chk_cotizaciones_pdf_job_id_not_empty
        CHECK (pdf_job_id IS NULL OR length(trim(pdf_job_id)) > 0),
    CONSTRAINT chk_cotizaciones_source_snapshot_object
        CHECK (jsonb_typeof(cotizacion_source_snapshot) = 'object'),
    CONSTRAINT chk_cotizaciones_analysis_summary_object
        CHECK (jsonb_typeof(analysis_summary) = 'object'),
    CONSTRAINT chk_cotizaciones_questions_decision_object
        CHECK (jsonb_typeof(questions_decision) = 'object'),
    CONSTRAINT chk_cotizaciones_questions_for_ui_array
        CHECK (jsonb_typeof(questions_for_ui) = 'array'),
    CONSTRAINT chk_cotizaciones_questionnaire_answers_array
        CHECK (jsonb_typeof(questionnaire_answers) = 'array'),
    CONSTRAINT chk_cotizaciones_pricing_payload_object
        CHECK (jsonb_typeof(pricing_canonical_payload) = 'object'),
    CONSTRAINT chk_cotizaciones_excel_payload_object
        CHECK (jsonb_typeof(excel_canonical_payload) = 'object'),
    CONSTRAINT chk_cotizaciones_pdf_payload_object
        CHECK (jsonb_typeof(pdf_render_payload) = 'object'),
    CONSTRAINT chk_cotizaciones_created_by_login_positive
        CHECK (created_by_login_id > 0),
    CONSTRAINT chk_cotizaciones_created_by_user_positive
        CHECK (created_by_user_id IS NULL OR created_by_user_id > 0),
    CONSTRAINT chk_cotizaciones_updated_by_login_positive
        CHECK (updated_by_login_id IS NULL OR updated_by_login_id > 0)
);

CREATE TABLE IF NOT EXISTS commerce.cotizaciones_items (
    id_cotizacion_item BIGSERIAL PRIMARY KEY,
    id_cotizacion BIGINT NOT NULL,
    business_id VARCHAR(100) NOT NULL,
    orden INTEGER NOT NULL,
    id_item INTEGER,
    tipo_item SMALLINT NOT NULL,
    nombre_item_snapshot VARCHAR(255) NOT NULL,
    cantidad INTEGER NOT NULL,
    precio_unitario_base NUMERIC(14,2) NOT NULL,
    precio_unitario_cliente NUMERIC(14,2) NOT NULL,
    monto_base NUMERIC(14,2) NOT NULL,
    monto_total_cliente NUMERIC(14,2) NOT NULL,
    id_variante INTEGER,
    variante_strategy VARCHAR(32),
    promocion_snapshot JSONB NOT NULL DEFAULT '{}'::jsonb,
    articulo_snapshot JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT fk_cotizaciones_items_cotizacion
        FOREIGN KEY (id_cotizacion)
        REFERENCES commerce.cotizaciones (id_cotizacion)
        ON UPDATE CASCADE
        ON DELETE CASCADE,
    CONSTRAINT chk_cotizaciones_items_business_id_not_empty
        CHECK (length(trim(business_id)) > 0),
    CONSTRAINT chk_cotizaciones_items_orden_positive
        CHECK (orden > 0),
    CONSTRAINT chk_cotizaciones_items_tipo_item
        CHECK (tipo_item IN (0, 1)),
    CONSTRAINT chk_cotizaciones_items_nombre_not_empty
        CHECK (length(trim(nombre_item_snapshot)) > 0),
    CONSTRAINT chk_cotizaciones_items_cantidad_positive
        CHECK (cantidad > 0),
    CONSTRAINT chk_cotizaciones_items_precio_unitario_base_non_negative
        CHECK (precio_unitario_base >= 0),
    CONSTRAINT chk_cotizaciones_items_precio_unitario_cliente_non_negative
        CHECK (precio_unitario_cliente >= 0),
    CONSTRAINT chk_cotizaciones_items_monto_base_non_negative
        CHECK (monto_base >= 0),
    CONSTRAINT chk_cotizaciones_items_monto_total_cliente_non_negative
        CHECK (monto_total_cliente >= 0),
    CONSTRAINT chk_cotizaciones_items_total_cliente_ge_base
        CHECK (monto_total_cliente >= monto_base),
    CONSTRAINT chk_cotizaciones_items_promocion_snapshot_object
        CHECK (jsonb_typeof(promocion_snapshot) = 'object'),
    CONSTRAINT chk_cotizaciones_items_articulo_snapshot_object
        CHECK (jsonb_typeof(articulo_snapshot) = 'object'),
    CONSTRAINT chk_cotizaciones_items_variante_strategy_not_empty
        CHECK (variante_strategy IS NULL OR length(trim(variante_strategy)) > 0)
);

CREATE TABLE IF NOT EXISTS commerce.cotizaciones_archivos (
    id_cotizacion_archivo BIGSERIAL PRIMARY KEY,
    id_cotizacion BIGINT NOT NULL,
    business_id VARCHAR(100) NOT NULL,
    tipo_archivo VARCHAR(16) NOT NULL,
    ruta_relativa VARCHAR(500) NOT NULL,
    nombre_archivo VARCHAR(255) NOT NULL,
    mime_type VARCHAR(120) NOT NULL,
    tamanio_bytes INTEGER NOT NULL,
    sha256 VARCHAR(64) NOT NULL,
    metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
    es_activo BOOLEAN NOT NULL DEFAULT TRUE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    created_by_login_id INTEGER NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_by_login_id INTEGER,
    soft_delete BOOLEAN NOT NULL DEFAULT FALSE,
    soft_delete_date TIMESTAMPTZ,
    CONSTRAINT fk_cotizaciones_archivos_cotizacion
        FOREIGN KEY (id_cotizacion)
        REFERENCES commerce.cotizaciones (id_cotizacion)
        ON UPDATE CASCADE
        ON DELETE CASCADE,
    CONSTRAINT chk_cotizaciones_archivos_business_id_not_empty
        CHECK (length(trim(business_id)) > 0),
    CONSTRAINT chk_cotizaciones_archivos_tipo
        CHECK (tipo_archivo IN ('pdf', 'xlsx')),
    CONSTRAINT chk_cotizaciones_archivos_ruta_relativa_not_empty
        CHECK (length(trim(ruta_relativa)) > 0),
    CONSTRAINT chk_cotizaciones_archivos_nombre_not_empty
        CHECK (length(trim(nombre_archivo)) > 0),
    CONSTRAINT chk_cotizaciones_archivos_mime_type_not_empty
        CHECK (length(trim(mime_type)) > 0),
    CONSTRAINT chk_cotizaciones_archivos_tamanio_non_negative
        CHECK (tamanio_bytes >= 0),
    CONSTRAINT chk_cotizaciones_archivos_sha256_hex
        CHECK (sha256 ~ '^[a-f0-9]{64}$'),
    CONSTRAINT chk_cotizaciones_archivos_metadata_object
        CHECK (jsonb_typeof(metadata) = 'object'),
    CONSTRAINT chk_cotizaciones_archivos_created_by_login_positive
        CHECK (created_by_login_id > 0),
    CONSTRAINT chk_cotizaciones_archivos_updated_by_login_positive
        CHECK (updated_by_login_id IS NULL OR updated_by_login_id > 0)
);

CREATE INDEX IF NOT EXISTS cotizaciones_business_id_idx
    ON commerce.cotizaciones (business_id);

CREATE INDEX IF NOT EXISTS cotizaciones_fecha_cotizacion_idx
    ON commerce.cotizaciones (fecha_cotizacion);

CREATE INDEX IF NOT EXISTS cotizaciones_id_cliente_idx
    ON commerce.cotizaciones (id_cliente);

CREATE INDEX IF NOT EXISTS cotizaciones_estado_general_idx
    ON commerce.cotizaciones (estado_general);

CREATE INDEX IF NOT EXISTS cotizaciones_preflight_status_idx
    ON commerce.cotizaciones (preflight_status);

CREATE INDEX IF NOT EXISTS cotizaciones_excel_status_idx
    ON commerce.cotizaciones (excel_status);

CREATE INDEX IF NOT EXISTS cotizaciones_pdf_status_idx
    ON commerce.cotizaciones (pdf_status);

CREATE INDEX IF NOT EXISTS cotizaciones_modelo_contexto_idx
    ON commerce.cotizaciones (id_modelo_plan_pago_contexto)
    WHERE id_modelo_plan_pago_contexto IS NOT NULL;

CREATE INDEX IF NOT EXISTS cotizaciones_soft_delete_idx
    ON commerce.cotizaciones (soft_delete);

CREATE INDEX IF NOT EXISTS cotizaciones_sucursal_idx
    ON commerce.cotizaciones USING gin (sucursal);

CREATE UNIQUE INDEX IF NOT EXISTS uq_cotizaciones_business_folio_active
    ON commerce.cotizaciones (business_id, folio_cotizacion)
    WHERE soft_delete IS NOT TRUE
      AND folio_cotizacion IS NOT NULL;

CREATE INDEX IF NOT EXISTS cotizaciones_items_cotizacion_idx
    ON commerce.cotizaciones_items (id_cotizacion, orden);

CREATE INDEX IF NOT EXISTS cotizaciones_items_business_id_idx
    ON commerce.cotizaciones_items (business_id);

CREATE INDEX IF NOT EXISTS cotizaciones_items_id_item_idx
    ON commerce.cotizaciones_items (id_item)
    WHERE id_item IS NOT NULL;

CREATE INDEX IF NOT EXISTS cotizaciones_items_id_variante_idx
    ON commerce.cotizaciones_items (id_variante)
    WHERE id_variante IS NOT NULL;

CREATE INDEX IF NOT EXISTS cotizaciones_archivos_cotizacion_idx
    ON commerce.cotizaciones_archivos (id_cotizacion);

CREATE INDEX IF NOT EXISTS cotizaciones_archivos_business_id_idx
    ON commerce.cotizaciones_archivos (business_id);

CREATE INDEX IF NOT EXISTS cotizaciones_archivos_sha256_idx
    ON commerce.cotizaciones_archivos (sha256);

CREATE UNIQUE INDEX IF NOT EXISTS uq_cotizaciones_archivos_activo
    ON commerce.cotizaciones_archivos (business_id, id_cotizacion, tipo_archivo)
    WHERE soft_delete IS NOT TRUE
      AND es_activo = TRUE;

COMMENT ON TABLE commerce.cotizaciones IS 'Cotizaciones generadas desde agregar-venta con persistencia temprana, estados de preflight/documentos y snapshots comerciales congelados.';
COMMENT ON COLUMN commerce.cotizaciones.id_cotizacion IS 'Identificador tecnico de la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.business_id IS 'Tenant del negocio propietario de la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.sucursal IS 'Array PostgreSQL de sucursal operativa. En este flujo contiene exactamente una sucursal.';
COMMENT ON COLUMN commerce.cotizaciones.id_cliente IS 'Cliente seleccionado en agregar-venta y ligado a la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.id_modelo_plan_pago_contexto IS 'Modelo de plan de pago seleccionado como contexto comercial cuando la cotizacion nace desde venta con plan.';
COMMENT ON COLUMN commerce.cotizaciones.folio_cotizacion IS 'Folio visible opcional de la cotizacion cuando exista numeracion comercial externa.';
COMMENT ON COLUMN commerce.cotizaciones.fecha_cotizacion IS 'Fecha operativa efectiva de la cotizacion, alineada a la fecha seleccionada en tarjeta-transaccion.';
COMMENT ON COLUMN commerce.cotizaciones.vigencia_hasta IS 'Fecha limite comercial opcional de vigencia de la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.currency_code IS 'Codigo ISO 4217 congelado al momento de generar la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.document_option_mode IS 'Modo documental elegido en frontend: pdf_only o pdf_and_excel.';
COMMENT ON COLUMN commerce.cotizaciones.estado_general IS 'Estado general del flujo de cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.preflight_status IS 'Estado de la etapa remota de preflight y preguntas.';
COMMENT ON COLUMN commerce.cotizaciones.excel_status IS 'Estado de la etapa remota de Excel.';
COMMENT ON COLUMN commerce.cotizaciones.pdf_status IS 'Estado de la etapa remota de PDF.';
COMMENT ON COLUMN commerce.cotizaciones.preflight_job_id IS 'Job remoto de Brain asociado al preflight.';
COMMENT ON COLUMN commerce.cotizaciones.excel_job_id IS 'Job remoto de Brain asociado a la generacion de Excel.';
COMMENT ON COLUMN commerce.cotizaciones.pdf_job_id IS 'Job remoto de Brain asociado a la generacion de PDF.';
COMMENT ON COLUMN commerce.cotizaciones.cotizacion_source_snapshot IS 'Fuente comercial congelada salida de tarjeta-transaccion, sin flags documentales.';
COMMENT ON COLUMN commerce.cotizaciones.analysis_summary IS 'Resumen estructurado del analisis inicial generado por Brain.';
COMMENT ON COLUMN commerce.cotizaciones.questions_decision IS 'Decision del preflight sobre si hacen falta preguntas y cuales.';
COMMENT ON COLUMN commerce.cotizaciones.questions_for_ui IS 'Arreglo JSON parseable para renderizar preguntas en frontend.';
COMMENT ON COLUMN commerce.cotizaciones.questionnaire_answers IS 'Arreglo JSON con respuestas del usuario a las preguntas de la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.pricing_canonical_payload IS 'Payload matematico comun y persistido del flujo documental.';
COMMENT ON COLUMN commerce.cotizaciones.excel_canonical_payload IS 'Payload especifico para render o regeneracion de Excel.';
COMMENT ON COLUMN commerce.cotizaciones.pdf_render_payload IS 'Payload especifico para render o regeneracion de PDF.';
COMMENT ON COLUMN commerce.cotizaciones.created_at IS 'Timestamp de creacion del registro de cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.created_by_login_id IS 'Login humano que inicio la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.created_by_user_id IS 'Usuario workforce asociado al login humano cuando exista.';
COMMENT ON COLUMN commerce.cotizaciones.updated_at IS 'Timestamp de ultima modificacion de la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.updated_by_login_id IS 'Login humano que actualizo por ultima vez la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.soft_delete IS 'Bandera de borrado logico de la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones.soft_delete_date IS 'Timestamp de borrado logico de la cotizacion.';

COMMENT ON TABLE commerce.cotizaciones_items IS 'Renglones congelados de cada cotizacion para consulta y regeneracion futura sin depender del catalogo vivo.';
COMMENT ON COLUMN commerce.cotizaciones_items.id_cotizacion_item IS 'Identificador tecnico del renglon de cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones_items.id_cotizacion IS 'Cotizacion padre a la que pertenece el renglon.';
COMMENT ON COLUMN commerce.cotizaciones_items.business_id IS 'Tenant del negocio propietario del renglon.';
COMMENT ON COLUMN commerce.cotizaciones_items.orden IS 'Orden visible del renglon dentro de la cotizacion.';
COMMENT ON COLUMN commerce.cotizaciones_items.id_item IS 'ID del producto o servicio original cuando exista.';
COMMENT ON COLUMN commerce.cotizaciones_items.tipo_item IS '0=producto, 1=servicio.';
COMMENT ON COLUMN commerce.cotizaciones_items.nombre_item_snapshot IS 'Nombre congelado del articulo al momento de cotizar.';
COMMENT ON COLUMN commerce.cotizaciones_items.cantidad IS 'Cantidad cotizada del renglon.';
COMMENT ON COLUMN commerce.cotizaciones_items.precio_unitario_base IS 'Precio unitario base comercial antes del efecto del metodo de pago al cliente.';
COMMENT ON COLUMN commerce.cotizaciones_items.precio_unitario_cliente IS 'Precio unitario final visto por el cliente para el renglon.';
COMMENT ON COLUMN commerce.cotizaciones_items.monto_base IS 'Importe base total del renglon.';
COMMENT ON COLUMN commerce.cotizaciones_items.monto_total_cliente IS 'Importe total final del renglon para el cliente.';
COMMENT ON COLUMN commerce.cotizaciones_items.id_variante IS 'Variante aplicada al renglon cuando existe.';
COMMENT ON COLUMN commerce.cotizaciones_items.variante_strategy IS 'Estrategia de resolucion de variante congelada en el renglon.';
COMMENT ON COLUMN commerce.cotizaciones_items.promocion_snapshot IS 'Metadata promocional congelada del renglon.';
COMMENT ON COLUMN commerce.cotizaciones_items.articulo_snapshot IS 'Snapshot libre del articulo con precios, variante, metodo y metadata relevante.';
COMMENT ON COLUMN commerce.cotizaciones_items.created_at IS 'Timestamp de creacion del renglon de cotizacion.';

COMMENT ON TABLE commerce.cotizaciones_archivos IS 'Metadata de artefactos documentales generados para cada cotizacion, sin guardar el binario dentro de PostgreSQL.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.id_cotizacion_archivo IS 'Identificador tecnico del artefacto documental.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.id_cotizacion IS 'Cotizacion padre a la que pertenece el artefacto.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.business_id IS 'Tenant del negocio propietario del artefacto.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.tipo_archivo IS 'Tipo de artefacto generado: pdf o xlsx.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.ruta_relativa IS 'Ruta privada relativa del artefacto persistido fuera de la base de datos.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.nombre_archivo IS 'Nombre de archivo persistido para descarga.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.mime_type IS 'MIME type detectado del artefacto generado.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.tamanio_bytes IS 'Tamano del artefacto persistido en bytes.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.sha256 IS 'Hash SHA-256 del artefacto para auditoria e integridad.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.metadata IS 'Metadata extensible del archivo generado.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.es_activo IS 'Bandera del archivo actualmente vigente para ese tipo documental.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.created_at IS 'Timestamp de creacion del registro de archivo.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.created_by_login_id IS 'Login humano que disparo la generacion del artefacto.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.updated_at IS 'Timestamp de ultima actualizacion del artefacto.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.updated_by_login_id IS 'Login humano que actualizo por ultima vez el registro del artefacto.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.soft_delete IS 'Bandera de borrado logico del archivo.';
COMMENT ON COLUMN commerce.cotizaciones_archivos.soft_delete_date IS 'Timestamp de borrado logico del archivo.';

INSERT INTO ops.canonical_table_map (table_name, canonical_schema, notes)
VALUES
    (
        'cotizaciones',
        'commerce',
        'Encabezado canonico de cotizaciones generadas desde agregar-venta con snapshots, estados y payloads documentales'
    ),
    (
        'cotizaciones_items',
        'commerce',
        'Renglones canonicos de cotizaciones con variante, promocion y precios congelados'
    ),
    (
        'cotizaciones_archivos',
        'commerce',
        'Artefactos documentales canonicos asociados a cotizaciones'
    )
ON CONFLICT (table_name) DO UPDATE
SET canonical_schema = EXCLUDED.canonical_schema,
    notes = EXCLUDED.notes;

ANALYZE commerce.cotizaciones;
ANALYZE commerce.cotizaciones_items;
ANALYZE commerce.cotizaciones_archivos;
