-- =====================================================
-- Migration 003: Ciclos (a missão de um dia)
-- Feature: inventario-ciclico
-- Data: 2026-06-29
-- =====================================================
--
-- Um ciclo representa o trabalho de um dia do plano: o conjunto de alvos
-- selecionados e a missão AlocacaoWms gerada para executá-los. A volta
-- (contagens) é lida de wms_movimentos por missao_logistica_id; o ciclo
-- guarda um snapshot dos alvos (alvos_ref) para auditoria e para o roteiro
-- exibido ao operador.
--
-- hash_idempotencia = md5("invciclo:{plano_id}:{data_ciclo}") garante que
-- o cron não duplique o ciclo se rodar duas vezes no mesmo dia.
-- Block columns sem DEFAULT (feedback_block_columns).
-- =====================================================

CREATE TABLE IF NOT EXISTS inventario_ciclos (
    id                  SERIAL PRIMARY KEY,

    plano_id            INTEGER     NOT NULL,
    campanha_numero     INTEGER     NOT NULL DEFAULT 1,
    data_ciclo          DATE        NOT NULL,
    missao_logistica_id INTEGER,                                  -- missão AlocacaoWms gerada (ALOCACAO_WMS)
    qtd_alvos           INTEGER     NOT NULL DEFAULT 0,
    alvos_ref           JSONB,                                    -- snapshot [{alvo_id, tipo, ref, descricao}]
    status              VARCHAR(20) NOT NULL DEFAULT 'agendado',  -- agendado | em_andamento | concluido | parcial | cancelado
    hash_idempotencia   VARCHAR(64),
    fechado_em          TIMESTAMP WITHOUT TIME ZONE,

    -- Audit/block padrão Galaxia (injetado pelo framework no create/update; sem DEFAULT).
    -- Espelha o conjunto de wms_movimentos — ModelInteligencia::create() exige estas colunas.
    data_cadastro       TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
    usuario_cadastro    VARCHAR(120),
    data_atualizacao    TIMESTAMP WITHOUT TIME ZONE,
    usuario_atualizacao VARCHAR(120),
    block_data          TIMESTAMP WITHOUT TIME ZONE,
    block_quem          VARCHAR(120),
    block_filial_id     INTEGER,
    block_usuario_id    INTEGER,
    block_empresa_id    INTEGER,
    block               INTEGER
);

-- Idempotência por (plano, dia) dentro do tenant
CREATE UNIQUE INDEX IF NOT EXISTS uniq_inv_ciclo_idem ON inventario_ciclos (hash_idempotencia, block);

CREATE INDEX IF NOT EXISTS idx_inv_ciclo_plano  ON inventario_ciclos (plano_id, block);
CREATE INDEX IF NOT EXISTS idx_inv_ciclo_data   ON inventario_ciclos (plano_id, data_ciclo);
CREATE INDEX IF NOT EXISTS idx_inv_ciclo_missao ON inventario_ciclos (missao_logistica_id);
