Code: Promessa que “aumenta conversão” mas atrasa em certos CEPs

Este é um problema real em e-commerce e marketplaces: ao encurtar prazos prometidos no checkout, a conversão sobe. Só que, após alguns ciclos, aparecem sinais estranhos: aumento de “atrasou”, mais cancelamentos e mais tickets — concentrados em regiões específicas. Na média, o indicador parece saudável; na cauda, a confiança quebra.

Aqui, Code Map (CM) é um diagnóstico: mapear em quais coortes (por exemplo, prefixo de CEP, tipo de moradia, janela de recebimento, transportadora) a promessa está falhando mais, e se o sistema está “comprando conversão” com a moeda de um grupo específico.

AS-IS — promessa agressiva por média, sem visibilidade de coorte

No AS-IS, o sistema promete com base em um ETA “pontual” (um único número) e um ajuste global. Ele não mede taxa de atraso por coorte, não incorpora variância local e trata “prometer curto” como uma alavanca universal. O resultado típico é overpromise em corredores com alta incerteza — e isso tende a se concentrar em regiões onde a variabilidade é estrutural.

# AS-IS: promete prazo com base em ETA pontual + ajuste global.
# Problemas típicos:
# - usa média/mediana global; não calibra por coorte
# - ignora variância (corredores com alta incerteza)
# - não registra recibo por coorte para diagnóstico CM
# - otimiza conversão, mas redistribui atrasos para grupos específicos

from dataclasses import dataclass
from typing import Dict, Any

@dataclass
class CheckoutContext:
    order_id: str
    sku: str
    warehouse: str
    carrier: str
    delivery_zip: str
    is_peak: bool
    promised_days_cap: int  # marketing/negócio (ex.: não prometer acima de X)

def eta_point_estimate(features: Dict[str, Any]) -> float:
    # Placeholder: modelo de ETA em dias (pontual)
    base = 2.0
    base += 1.2 if features["is_peak"] else 0.0
    base += 0.8 if features["carrier"] == "econ" else 0.0
    base += 0.6 if features["delivery_zip"].startswith(("0", "1")) else 0.0  # proxy bruto (exemplo)
    return base

def promise_days_as_is(ctx: CheckoutContext) -> Dict[str, Any]:
    features = {
        "warehouse": ctx.warehouse,
        "carrier": ctx.carrier,
        "delivery_zip": ctx.delivery_zip,
        "is_peak": ctx.is_peak,
    }
    eta_days = eta_point_estimate(features)

    # Ajuste global “para competir”: encurta a promessa em 0.5 dia
    promised = max(1, int(round(eta_days - 0.5)))

    # Cap global de promessa (piora overpromise quando a rota é ruim)
    promised = min(promised, ctx.promised_days_cap)

    return {
        "order_id": ctx.order_id,
        "promised_days": promised,
        "eta_point_days": eta_days,
        "carrier": ctx.carrier,
        "delivery_zip": ctx.delivery_zip,
    }

O CM aparece quando a empresa cruza o “atrasou vs prometido” por coorte e percebe que a promessa curta está concentrando falha: um prefixo de CEP, uma transportadora específica, uma combinação warehouse→rota. Sem recibo por coorte e sem variância, o time só enxerga sintomas (“reclamações em tal região”) e reage com exceções (bloquear CEP, aumentar prazo para todos, trocar transportadora às pressas).

TO-BE — promessa governável: calibrar por coorte, incluir incerteza e registrar recibos

No TO-BE, o diagnóstico CM recomenda três mudanças práticas: (1) prometer usando distribuição (não só um ponto), (2) calibrar por coorte operacional para não esconder concentração, e (3) registrar recibos para replay e correção. A promessa deixa de ser “um número agressivo” e vira “um compromisso com controle de cauda”.

# TO-BE: promete usando quantil (ex.: p85/p90), calibra por coorte e registra recibo.
# Melhorias:
# - cria chave de coorte operacional para medir e governar concentração
# - usa previsão com incerteza (quantis) para evitar overpromise em rotas variáveis
# - aplica política: quando incerteza é alta, ampliar janela/mostrar faixa/alternativas
# - registra recibo replayável para diagnóstico CM

from dataclasses import dataclass
from typing import Dict, Any, Tuple
import time
import uuid

@dataclass
class CheckoutContext:
    order_id: str
    sku: str
    warehouse: str
    carrier: str
    delivery_zip: str
    is_peak: bool
    promised_days_cap: int
    pickup_available: bool

POLICY_VERSION = "promise_policy_v2.4"

def cohort_key(ctx: CheckoutContext) -> str:
    zip_prefix = ctx.delivery_zip[:2] if ctx.delivery_zip else "??"
    return f"zip:{zip_prefix}|wh:{ctx.warehouse}|car:{ctx.carrier}|peak:{int(ctx.is_peak)}"

def eta_quantiles(features: Dict[str, Any]) -> Tuple[float, float, float]:
    """
    Placeholder: retorna quantis (p50, p85, p95) em dias.
    Em produção isso viria de um modelo calibrado ou de um modelo + calibrador por rota.
    """
    p50 = 2.2
    p50 += 1.1 if features["is_peak"] else 0.0
    p50 += 0.7 if features["carrier"] == "econ" else 0.0

    # Incerteza aumenta em certas rotas (exemplo simplificado)
    uncertainty = 0.6
    uncertainty += 0.8 if features["delivery_zip"].startswith(("0", "1")) else 0.0
    uncertainty += 0.5 if features["carrier"] == "econ" else 0.0
    uncertainty += 0.7 if features["is_peak"] else 0.0

    p85 = p50 + 0.9 * uncertainty
    p95 = p50 + 1.5 * uncertainty
    return (p50, p85, p95)

def policy_promise(ctx: CheckoutContext, p50: float, p85: float, p95: float) -> Dict[str, Any]:
    # Política: prometer baseado em p85 por padrão (controla cauda),
    # e se a incerteza for alta, degradar para janela (faixa) e/ou oferecer pickup.
    spread = p95 - p50

    # Regra: evitar promessa irreversível curta quando spread é alto.
    if spread >= 2.5:
        # “Hesitação”: não cravar um dia só; oferecer faixa e alternativa
        low = max(1, int(round(p85)))
        high = max(low, int(round(p95)))
        low = min(low, ctx.promised_days_cap)
        high = min(high, max(low, ctx.promised_days_cap))
        return {
            "promise_type": "range",
            "promised_days_low": low,
            "promised_days_high": high,
            "offer_pickup": ctx.pickup_available,
            "policy_notes": ["high_uncertainty:use_range", "avoid_overpromise"],
        }

    # Caso normal: promessa em dia único usando p85
    promised = max(1, int(round(p85)))
    promised = min(promised, ctx.promised_days_cap)
    return {
        "promise_type": "single",
        "promised_days": promised,
        "offer_pickup": False,
        "policy_notes": ["use_p85"],
    }

def write_receipt(receipt: Dict[str, Any]) -> None:
    # Placeholder: log/audit + métricas por coorte (ex.: atraso vs promessa, taxa de “range”, etc.)
    print("[PROMISE_RECEIPT]", receipt)

def promise_days_to_be(ctx: CheckoutContext) -> Dict[str, Any]:
    request_id = f"pm_{uuid.uuid4().hex}"
    features = {
        "warehouse": ctx.warehouse,
        "carrier": ctx.carrier,
        "delivery_zip": ctx.delivery_zip,
        "is_peak": ctx.is_peak,
    }

    p50, p85, p95 = eta_quantiles(features)
    policy_out = policy_promise(ctx, p50, p85, p95)

    receipt = {
        "ts": int(time.time()),
        "request_id": request_id,
        "policy_version": POLICY_VERSION,
        "order_id": ctx.order_id,
        "cohort": cohort_key(ctx),
        "inputs": {
            "warehouse": ctx.warehouse,
            "carrier": ctx.carrier,
            "zip_prefix": (ctx.delivery_zip[:2] if ctx.delivery_zip else "??"),
            "is_peak": ctx.is_peak,
            "pickup_available": ctx.pickup_available,
        },
        "eta_quantiles_days": {"p50": p50, "p85": p85, "p95": p95},
        "decision": policy_out,
    }
    write_receipt(receipt)

    # Resposta para UI
    if policy_out["promise_type"] == "single":
        return {
            "order_id": ctx.order_id,
            "request_id": request_id,
            "promise_type": "single",
            "promised_days": policy_out["promised_days"],
            "offer_pickup": False,
        }
    else:
        return {
            "order_id": ctx.order_id,
            "request_id": request_id,
            "promise_type": "range",
            "promised_days_low": policy_out["promised_days_low"],
            "promised_days_high": policy_out["promised_days_high"],
            "offer_pickup": policy_out["offer_pickup"],
        }

Antes, a promessa era uma “alavanca global” que escondia concentração. Agora, o sistema passa a fazer três coisas que o CM exige para governar: rotular coorte, evitar irreversibilidade curta sob alta incerteza e deixar recibo replayável para corrigir onde a falha se concentra.

Análise — o que Code Map com código muda de verdade

O CM, aplicado a promessa de entrega, mostra um padrão comum: melhorar conversão na média pode significar piorar confiança em coortes específicas. O erro não é “prometer curto” em si; é prometer curto sem medir e sem controlar cauda por corredor operacional.

O TO-BE não “desacelera o negócio” por princípio. Ele muda a moeda: de promessa agressiva para compromisso governável. Em vez de esconder incerteza, ele a incorpora (faixa, alternativas) e reduz dano concentrado. E, ao registrar recibos por coorte, ele permite que a organização corrija com precisão (rota, transportadora, janela, cobertura), sem cair no padrão de “aumentar prazo para todo mundo” ou “bloquear regiões” como solução bruta.

Veja também: