Skip to main content

Decisões — Spike 198299 (grill-with-docs)

Data: 2026-07-09
Base: sp.md + pesquisa nos 5 repositórios
Nota: D1 foi proposta no grill interativo; UI de pergunta recusada — decisões por best judgment alinhadas ao código e à SP. Revisáveis antes da US de implementação.


Decisões

#TemaDecisãoRacional
D1Persistência de “sem expiração”Gravar DateTime.MaxValue no Elasticsearch; API/DTO/UI expõem null e o texto “Sem data de expiração”Padrão já usado na vitrine da marca no mesmo serviço (ShowCaseBrandCommandHandler: Elastic não aceita null em campo de data). Filtros DateExpiration >= now e IsExpired() funcionam com MaxValue. Null persistido arrisca sumir em date_range; null na Store hoje vira default +31 via SetDateExpiration.
D2Escopo de tiposStore + Recommendation. Brand/BrandSeller fora do CASP: menu Minhas + Histórico; atenção explícita de que marca é zzportal.
D3Default e máximo em diasManter +31 como no AS-IS do app/SetDateExpiration; documentar divergência com texto “+30” da SPEvitar inventar terceiro número na Spike; alinhamento PO é pré-dev (Fase 0).
D4Default na criação vs limpar dataUI preenche default; se usuário limpa, backend grava sem expiração (MaxValue), sem reaplicar +NCA-1 + CA-2: default da regra atual, mas remoção é ação explícita.
D5Vitrine já expiradaFora do escopo mínimo: continua fora de listagens/get ativosAS-IS não lista expiradas; reativação seria US à parte.
D6Unicidade Recommendation“Sem expiração” = ativa para unicidade userId + customerCpf + storeIdMesma definição de vitrine ativa.
D7Portal, web público, jobsSem mudança exigida pelos CAsMarca já opcional; showcase-web não modela expiração; jobs de produto não expiram vitrine de vendedor.
D8Teto de dias no backendPlano de US deve incluir validação de máximo no API se data informada (hoje só UI)SP: “respeitando o máximo 30 dias”; backend AS-IS sem cap.
D-APP-8Edição Minhas — detectar remoção da dataReplicar padrão Histórico: _initialExpirationDate, hasExpirationDateChanged via _isSameDate (null ↔ data), picker sempre visível com clear, enableEditButton inclui mudança de expiraçãoCódigo AS-IS só habilita salvar se expirationDate != null; limpar data não habilita botão. Alinha D4 e Sem data de expiração.
D-APP-9UX clear no ZZDateFormFieldOpção A: após clear, exibir texto legível no campo (não vazio); ícone X no suffix quando há data; texto parametrizável pelo caller (não hardcoded)Alinha zzportal (isClearable + placeholder). Vitrines passam copy CA-4; demais telas mantêm hint atual. allowClear default false.
D-APP-10Serialização JSON dateExpirationChave sempre presente no body; valor JSON null quando sem prazo (não omitir chave)Contrato explícito com API (D4); distingue clear intencional; testes de serialização validam "dateExpiration":null.
D-APP-11Dois fluxos de edição MinhasAplicar D-APP-8/D-APP-10 em detalhe e busca de produtos (show_case_search_products_controller): remover ?? +31 no PUT; setEditMode aceita DateTime?AS-IS só corrigiria um caminho; editar produtos pela busca reaplicaria +31 após clear.
D-APP-12Picker Histórico — data mínima no editAmanhã (+1 dia), igual ao create; max +31 em create e editAS-IS edit permite hoje; create usa amanhã. Alinha API (GreaterThan(now)) e Minhas.
D-APP-13Deploy API + appSimultâneo (mesmo release train); PR2 só após PR1 pronto; sem feature flag nesta USApp novo + API antiga quebra clear→null; RF-11.
D-APP-14Constante única +31 no zzappShowCaseExpirationDefaults.maxDaysFromNow = 31 + noExpirationLabelD3 pendente PO; espelha API ShowCaseExpirationRules; evita magic numbers espalhados.
D-APP-15Testes PR2Models obrigatórios; controllers desejáveis (_isSameDate, submit sem fallback) se acoplamento permitir teste unitário simples — senão, não forçar; smoke manual cobre controllersEvita testes frágeis por autoclosure/GetX; prioriza D-APP-10.
D-APP-16loadData Minhas sincroniza expiraçãoAo carregar detalhe/busca: expirationDate e _initialExpirationDate = valor da API (inclui null)Sem sync, PUT só de nome envia null e converte vitrine em never-expire por engano. Histórico já faz.

Decisões API (grill design showcase)

#TemaDecisãoRacional
D-API-7Validação Store ByAppCriar CreateShowCaseByAppValidator + UpdateShowCaseByAppValidator (regras de data compartilhadas): When(HasValue) + futura + cap MaxDaysFromNowCreateShowCaseValidator atual é vazio e valida outro command; endpoint zzapp usa ByApp sem validator. D8/RF-08.
D-API-8Cap +31 na APIInclusivo até início do dia (hoje + 31) em ToBrazillianTime(); regra compartilhada Store ByApp + RecommendParidade picker zzapp e filtros ES now/d; não usar instante Now.AddDays(31).
D-API-9Mínimo “data futura” na APIEstritamente após início de amanhã (dia civil BR via ToBrazillianTime()) — não GreaterThan(Now)Paridade D-APP-12 (picker min amanhã); regra compartilhada com cap D-API-8.
D-API-10Escopo ToApiExpirationTodos os DTOs de leitura Store/Recommend que expõem DateExpiration (inclui GET público)Evita 9999-12-31 no JSON; RF-07 uniforme; showcase-web sem mudança de UX.
D-API-11SetDates() no create RecommendRemover chamada no handler Recommend; manter método em ElasticBaseIndexSó 2 call sites: Recommend create (L112) e Brand temp CSV (L167). No Recommend, DateExpiration do SetDates() é sempre sobrescrito — efeito útil é só DateCreated. PR1 espelha Store (DateCreated explícito + normalizer). Brand temp ainda depende do método; refatorar fora do CA.

Contrato API recomendado (Store + Recommend)

Entrada dateExpirationSignificadoPersistência ES
Data futura (dentro do cap)Expira nessa datavalor informado
nullSem data de expiraçãoDateTime.MaxValue
(cliente) default preenchidoComportamento atual de prazodata default enviada

Default +N: responsabilidade primária do zzapp (já preenche). API não deve converter null em +31 (comportamento atual da Store que conflita com CA).

Saída DTO: se DateExpiration == DateTime.MaxValue → serializar/mapear como null (igual marca).


Cenários de borda

CenárioComportamento esperado
Create Minhas, não toca no campoVai com default +31 (UI) → expira
Create Minhas, limpa datanull → MaxValue → “Sem data de expiração”
Edit: remove data de vitrine com prazoMaxValue
Edit: adiciona data em “sem prazo”data informada (cap UI/API)
Recommend já ativa sem prazo, tenta criar outra para mesmo CPFBloqueado (unicidade)
Link público após +N em vitrine com prazo“Vitrine não encontrada” (AS-IS)
Link público em “sem prazo” após mesesContinua acessível se não deletada e produtos ok
Vitrine da marcaInalterada nesta US

Termos resolvidos no glossário

Ver CONTEXT.md: Vitrine de loja, Vitrine por histórico, Sem data de expiração, Vitrine ativa, Data de expiração vs exclusão.