fix: normalize campaign product size suffixes
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m44s

This commit is contained in:
Cauê Faleiros
2026-06-01 09:27:54 -03:00
parent b886b357d7
commit a1aa071e1d
5 changed files with 50 additions and 3 deletions

View File

@@ -94,6 +94,20 @@ const initDB = async () => {
ALTER COLUMN sent_at TYPE TIMESTAMPTZ USING sent_at AT TIME ZONE 'America/Sao_Paulo';
`).catch(() => {});
await pool.query(`
UPDATE stock_campaign_queue
SET base_product_name = TRIM(regexp_replace(
base_product_name,
'\\s+-\\s+(?:(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2})(?:/(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2}))*)$',
'',
'i'
))
WHERE status IN ('pending', 'failed', 'processing')
AND base_product_name ~* '\\s+-\\s+(?:(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2})(?:/(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2}))*)$';
`).catch(err => {
console.error('Notice: Could not normalize queued campaign product names:', err.message);
});
await pool.query(`CREATE INDEX IF NOT EXISTS idx_stock_campaign_queue_status ON stock_campaign_queue (status);`);
await pool.query(`CREATE INDEX IF NOT EXISTS idx_orders_cliente_fone ON orders (cliente_fone);`);
await pool.query(`CREATE INDEX IF NOT EXISTS idx_orders_produto_id ON orders (produto_id);`);

View File

@@ -1,4 +1,11 @@
const getBaseProductName = (name) => String(name || 'Unknown').split(' TAMANHO')[0].trim();
const SIZE_SUFFIX_PATTERN = /\s+-\s+(?:(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\d{2})(?:\/(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\d{2}))*)$/i;
const getBaseProductName = (name) => {
return String(name || 'Unknown')
.split(' TAMANHO')[0]
.replace(SIZE_SUFFIX_PATTERN, '')
.trim();
};
const normalizeStockPayload = (item) => {
const produtoId = item.idProduto || item.ID_Produto || '';

View File

@@ -1,6 +1,7 @@
const { pool } = require('../db');
const PRODUCT_NAME_SQL = "NULLIF(TRIM(split_part(COALESCE(produto_descricao, 'Unknown'), ' TAMANHO', 1)), '')";
const SIZE_SUFFIX_SQL_PATTERN = '\\s+-\\s+(?:(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2})(?:/(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\\d{2}))*)$';
const PRODUCT_NAME_SQL = `NULLIF(TRIM(regexp_replace(split_part(COALESCE(produto_descricao, 'Unknown'), ' TAMANHO', 1), '${SIZE_SUFFIX_SQL_PATTERN}', '', 'i')), '')`;
const normalizeDateParam = (value) => {
if (!value) return null;

View File

@@ -0,0 +1,23 @@
const assert = require('node:assert/strict');
const test = require('node:test');
const { getBaseProductName } = require('../mappers/stockMapper');
test('getBaseProductName strips TAMANHO suffixes', () => {
assert.equal(
getBaseProductName('BASE LISA CAMISETA COR BRANCO TAMANHO - P'),
'BASE LISA CAMISETA COR BRANCO'
);
});
test('getBaseProductName strips trailing size suffixes without removing colors', () => {
assert.equal(
getBaseProductName('BASE LISA MOLETOM CANGURU COR PRETO - M'),
'BASE LISA MOLETOM CANGURU COR PRETO'
);
assert.equal(
getBaseProductName('BASE LISA MOLETOM CANGURU COR PRETO - M/G/GG'),
'BASE LISA MOLETOM CANGURU COR PRETO'
);
assert.equal(getBaseProductName('BONÉ - BRANCO'), 'BONÉ - BRANCO');
});

View File

@@ -1,8 +1,10 @@
import type { DateRange, OrderData } from '../types';
import { parseOrderDate } from '../dataService';
const SIZE_SUFFIX_PATTERN = /\s+-\s+(?:(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\d{2})(?:\/(?:PP|P|M|G|GG|XG|XGG|EG|EGG|EXG|U|UNICO|ÚNICO|\d{2}))*)$/i;
export const getBaseProductName = (description: string): string => {
return description.split(' TAMANHO')[0];
return description.split(' TAMANHO')[0].replace(SIZE_SUFFIX_PATTERN, '').trim();
};
export const getClientDisplayName = (order: OrderData): string => {