Lógica do Sistema GAP
Este documento descreve como o sistema detecta, classifica e precifica gaps para cada tipo: normais, feriados e eventos.
🔵 Gaps Normais
O que é um gap normal?
Um gap é um período disponível entre duas reservas (ou entre hoje e a próxima reserva) no calendário de um imóvel. São detectados pelo script detect_gaps.py com dados do Sirius.
Critérios de inclusão
- Gap deve ser orphan: noites que ficam sozinhas entre reservas e dificilmente serão preenchidas sem ajuste de preço
- Duração: 1n (qualquer categoria 3Q+) ou 2-3n (apenas 3Q+)
- Categorias 1Q e 2Q: apenas 1n
- Horizonte: próximos 60 dias a partir de hoje
Urgência (urgencia)
| Valor | Critério |
|---|---|
| CRITICO | Gap com days_until_gap ≤ 2 OU min_stay travando OU double orphan |
| ALTO | days_until_gap ≤ 7 |
| MEDIO | days_until_gap ≤ 14 |
| IGNORAR | Gap distante ou sem ação necessária |
Urgency Tier (urgency_tier)
Dimensão usada na matriz de preços. Derivado de days_until_gap:
Preço Gapper (preco_gapper)
Calculado com base em descontos sobre o preco_base do imóvel:
O urgency_multiplier é lido da matriz _DISC2D (polígono × dia_semana × urgency_tier). Overrides do painel "Ajustar Descontos" sobrescrevem o valor calculado.
Pmin RM (pmin_rm)
Se o gap calculado ficar abaixo do Pmin RM do imóvel, o preço é elevado ao Pmin RM. Campo pmin_rm_travando = true indica que isso aconteceu.
Pmin Proprietário (pmin_prop)
Similar ao Pmin RM, mas definido pelo proprietário via comment_origin = 'proprietario' nas special_prices do Sirius. Campo pmin_prop_travando = true.
Double Orphan (double_orphan)
Gap de 2 noites em que ambas as noites estão isoladas (nenhuma reserva adjacente). Desconto elevado aplicado. Aparece na coluna Motivo como "Double Orphan".
Min-Stay (min_stay_vigente, min_stay_travado)
Se o imóvel tem min-stay configurado maior que as noites do gap, o gap nunca será preenchido. Campo sugestao_minstay indica o min-stay necessário para abrir o gap. origem_min_stay indica se a origem é rm (ajustável internamente) ou proprietario (requer CS).
Percentil de mercado (percentil_posicao)
Posição do preco_gapper em relação ao P05 dos concorrentes do comp set. Valor 13 = "entre os 13% mais baratos do mercado".
🎉 Gaps de Feriados
O que é um gap de feriado?
Gaps detectados pelo script detect_gaps_feriados.py para períodos de feriados nacionais (group_level ≥ 12). A lógica difere dos gaps normais: o desconto é calculado em relação ao preço praticado no Prime, não ao preço base puro.
Tipos de dia de feriado (gap_type)
| Tipo | Significado | Lógica de preço |
|---|---|---|
| prime | Dia de pico — maior demanda do feriado | Preço = preco_base × fator_demanda (sem desconto) |
| ponta | Dia adjacente ao prime — demanda menor | Preço = preco_prime × (1 − desconto_ponta_pct) |
| saida | Último dia do feriado — check-out | Preço = preco_prime × (1 − desconto_saida_pct) |
Campos exclusivos de feriados
gap_type: prime | ponta | saidapreco_praticado_real: preço atual do imóvel nesta data (do Sirius). Opreco_gapperé sempre ≤preco_praticado_real(regra D-F-001).preco_no_prime: preço do dia de pico para este feriadodesconto_prime_pct: desconto percentual em relação ao primegap_in_holiday_pct: % das noites do gap que caem dentro do feriadoi_demanda_gap: índice de demanda do gap (0-1)i_demanda_prime: índice de demanda do prime (0-1)ratio_gap_vs_prime: razão i_demanda_gap / i_demanda_primeferiado_nome: nome completo do feriado (ex: "Sexta-feira Santa")feriado_group_level: nível de abrangência (≥12 = nacional)cap_matrix_aplicado: indica se a matrix de caps foi aplicada no cálculo
Override de tipo de dia
No painel "Ajustar Descontos → Feriados", o usuário pode sobrescrever o tipo automático (prime/ponta/saída) para cada data do feriado, por cidade. Esses overrides ficam salvos no localStorage e alteram qual linha da matriz é usada para o preço.
Urgency Tier para feriados
Feriados não têm urgency_tier no JSON (campo null). O sistema deriva automaticamente via deriveTier(g) com base em days_until_gap.
🎪 Gaps de Eventos
O que é um gap de evento?
Eventos são feriados com group_level < 12 — ou seja, abrangência local/regional (show de banda em SP, maratona, etc.). A lógica de cálculo é idêntica à dos feriados, mas a classificação é tipo = "evento" para diferenciar na interface.
Diferenças em relação a feriados nacionais
group_level < 12: abrangência local- Aparecem apenas nas cidades dos imóveis afetados (após fix T-110 do Sirius)
- Exemplos: Guns N' Roses SP (apenas São Paulo), Maratona Internacional de SP
- Polígono não existe para eventos (assim como feriados) — filtro usa
cidade
Campos
Mesmos campos dos feriados: gap_type, preco_praticado_real, preco_no_prime, feriado_nome, etc.
🔄 Sincronização (sync.py)
O arquivo all_gaps.json é gerado pelo sync.py que une os três tipos:
GAP Detector/app/data/gaps.json→ tipo "normal"GAP Feriados/app/data/gaps_feriados.json→ tipo "feriado" (group_level ≥ 12) ou "evento" (group_level < 12)
Deduplicação: se o mesmo imóvel + data aparece nos dois JSONs, o registro de feriado prevalece (mais específico).
Regra D-F-001: preco_gapper = min(preco_gapper, preco_praticado_real) — o gapper nunca pode ser maior que o preço já praticado no imóvel.
