Skip to main content

Pesquisa — coezzion-service-showcase (API de vitrine)

Repo: /Users/alt-zz/projetos/arezzo/coezzion-service-showcase
Data: 2026-07-09
Escopo: expiração + CRUD de ShowCase


1. Visão geral

  • Persistência de vitrines: Elasticsearch (Nest), não SQL migrations para DateExpiration.
  • Índices: arezzo-showcase, arezzo-showcase-brand, arezzo-showcase-brand-seller, arezzo-showcase-recommend.
  • Tipos: ShowCaseType = Brand | Store | Recommendation | BrandSeller.
  • Sem CONTEXT.md / ADRs no repo. Doc útil: docs/features/feat_vitrine_recomendacao.md.

2. Modelo base de datas

Arquivo: src/ShowCase.Domain/Index/ElasticBaseIndex.cs

CampoTipoPapel
IdGuidId do documento
DateCreatedDateTimeCriação
DateDeletedDateTime?Soft-delete
DateExpirationDateTime?Expiração
public void SetDates(DateTime? date = null)
{
DateCreated = date is null ? DateTime.Now.ToBrazillianTime() : date.Value;
DateExpiration = DateCreated.AddDays(30);
}

public bool IsExpired() => DateExpiration < DateTime.Now.ToBrazillianTime();
// GetActiveObject(s): !IsDeleted && !IsExpired

Nota: comparação nullable em C# — se DateExpiration for null, IsExpired() retorna false (não expira). Porém listagens ES usam date range no campo (docs sem campo tendem a não casar).


3. Store (Minhas vitrines)

Entity

src/ShowCase.Domain/Entities/ShowCaseModel.cs:

public void SetDateExpiration(DateTime? date) =>
DateExpiration = date ?? DateCreated.AddDays(31).ToBrazillianTime();

Inconsistência: base usa +30; Store null usa +31.

Commands

OpHTTPCommand
CreatePOST api/show-case-new/CreateShowCaseByAppCommand (DateTime? DateExpiration)
UpdatePUT api/show-case-new/UpdateShowCaseByAppCommand
DeletePUT api/show-case-new/deleteDeleteShowCaseCommand (soft-delete)
GetGET api/show-case-new/{id}active-only
Get appGET api/show-case-new/app/{id}app
ListGET api/show-case-new/store/{storeId}ConfigureQueryActiveOnly

Handler: ShowCaseCommandHandler — create/update chamam showcase.SetDateExpiration(command.DateExpiration).

Validação: CreateShowCaseValidator efetivamente não valida expiração (sem FluentValidation de data na Store).

Listagem ativa

ShowCaseQueryHandler.ConfigureQueryActiveOnly:

  • MustNot DateDeleted exists
  • DateExpiration >= now/d

4. Recommendation (histórico de compras)

OpHTTP
CreatePOST api/show-case-new/recommend
UpdatePUT api/show-case-new/recommend/{id}
DeleteDELETE api/show-case-new/recommend/{id}
ListGET .../recommend/{storeId}/{page}/{size}

Commands: DateExpiration como DateTime não-nullable.

Validators (CreateShowCaseRecommendValidator / Update):

RuleFor(x => x.DateExpiration)
.NotEmpty().WithMessage("Data de expiração não informada!")
.GreaterThan(DateTime.Now).WithMessage("Data de expiração deve ser futura!");

Sem teto máximo no backend.

Handler create: SetDates() depois sobrescreve com command.DateExpiration.

Unicidade ativa: FindActiveByUserCustomerCpfAndStoreAsync — user + cpf + store, com DateExpiration >= now e sem delete.


5. Brand (fora do CA, precedente crítico)

Update header:

showCaseBrand.DateExpiration = command.DateExpiration == null
? DateTime.MaxValue
: command.DateExpiration; // Elastic não aceita null em campo de data

Queries: DateExpiration == DateTime.MaxValue ? null : DateExpiration no DTO.

Status: ativo se StartDate <= now && DateExpiration >= now.

Job (via jobs service): PUT .../brand/update-status recalcula Status.

Temp create: SetDates() → +30 dias.


6. BrandSeller

Na criação, copia DateExpiration do parent Brand (snapshot).


7. Get by id / repositório

ElasticBaseRepository.GetByIdShowCaseGetActiveObject() (null se deleted ou expired).
Variante GetByIdShowCaseNoValidateActive para admin/delete.


8. Impacto da Spike neste repo

ÁreaMudança necessária?
SetDateExpiration null → +31Sim — conflita com “null = sem prazo”
Validators RecommendSim — tornar opcional
Commands Recommend DateTimeDateTime?Sim
Map MaxValue → null nos DTOs Store/RecommendSim (Brand já faz)
Filtros ES com MaxValueOk sem mudança de query
IsExpired com MaxValueOk (MaxValue < now é false)
Job product listenersNão (estoque/preço)

Arquivos-chave

  • ShowCase.Domain/Index/ElasticBaseIndex.cs
  • ShowCase.Domain/Entities/ShowCaseModel.cs
  • ShowCase.Api/.../ShowCaseCommand/*
  • ShowCase.Api/.../ShowCaseRecommendCommand/*
  • ShowCase.Api/Application/Validators/CreateShowCaseRecommendValidator.cs
  • ShowCase.Api/Application/Validators/UpdateShowCaseRecommendValidator.cs
  • ShowCase.Api/.../ShowCaseQuery/ShowCaseQueryHandler.cs
  • ShowCase.Api/.../ShowCaseBrandCommand/ShowCaseBrandCommandHandler.cs (referência MaxValue)
  • Unit tests em ShowCase.UnitTest/Application/Validators/*Recommend*

9. Constantes mágicas

LocalValor
SetDates+30 dias
SetDateExpiration+31 dias se null
Brand nullDateTime.MaxValue
“Nova” marca (count)janela ~3 dias (não é expiração)