| 1234567891011121314151617181920212223242526272829303132333435363738394041 |
- -- Histórico de vendas vindas do CRM.
- --
- -- Cada venda é uma LINHA com a data em que ocorreu (sale_occurred_at). É essa
- -- dimensão de tempo que permite responder "faturado hoje / na semana / no mês",
- -- algo impossível com o contador agregado sku.sku_sold.
- --
- -- O sku.sku_sold continua existindo como total acumulado (cache de leitura
- -- rápida), incrementado pela aplicação a cada nova venda registrada aqui.
- --
- -- Isolamento: company_id é resolvido pela URL/HMAC do webhook, nunca pelo corpo.
- -- sku_id / client_id / operator_id são INT DEFAULT 0 (sem FK), seguindo o mesmo
- -- padrão adotado em integration.user_id/operator_id (migrations_v2): 0 = não
- -- vinculado, pois o CRM pode mandar uma venda sem produto/cliente/operador
- -- cadastrado na plataforma.
- CREATE TABLE IF NOT EXISTS sale (
- sale_id SERIAL PRIMARY KEY,
- company_id INT NOT NULL,
- sku_id INT NOT NULL DEFAULT 0,
- client_id INT NOT NULL DEFAULT 0,
- operator_id INT NOT NULL DEFAULT 0,
- sale_external_id TEXT NOT NULL,
- sale_amount DECIMAL(12,2) NOT NULL,
- sale_quantity INT NOT NULL DEFAULT 1,
- sale_occurred_at TIMESTAMP NOT NULL,
- sale_created_at TIMESTAMP NOT NULL DEFAULT NOW(),
- sale_deleted_at TIMESTAMP NOT NULL DEFAULT 'infinity',
- CONSTRAINT fk_sale_company FOREIGN KEY (company_id) REFERENCES company(company_id)
- );
- -- Idempotência: o CRM pode reenviar a mesma venda. A chave (company_id,
- -- sale_external_id) impede duplicar o faturamento. Parcial em registros ativos
- -- para conviver com a exclusão lógica.
- CREATE UNIQUE INDEX IF NOT EXISTS uq_sale_company_external_active
- ON sale (company_id, sale_external_id)
- WHERE sale_deleted_at = 'infinity';
- -- Acelera as consultas de faturamento por período (dia/semana/mês).
- CREATE INDEX IF NOT EXISTS idx_sale_company_occurred
- ON sale (company_id, sale_occurred_at)
- WHERE sale_deleted_at = 'infinity';
|