Skip to content

[Janela Simulado] Card 01 · ms-simulado · Schema disponivelDe/disponivelAte + funções de availability + índice #161

Description

@FernandoAlmeidaPinto

[Janela Simulado] Card 01 · ms-simulado · Schema disponivelDe/disponivelAte + funções de availability + índice

Projeto: ms-simulado
Etapa: 5 (Janela Simulado — docs/simulado-janela-disponibilidade.md)
Estimativa: S
Bloqueia: Card 02
Bloqueado por:


Descrição

Adiciona os dois campos de janela temporal em Simulado (disponivelDe, disponivelAte, ambos Date | null) e cria o módulo availability.ts com as funções puras isSimuladoAvailable e getAvailabilityStatus — fonte única de verdade sobre "esse simulado tá disponível agora?". Adiciona também o índice composto que o filtro do getAvailable (Card 02) vai depender.

Sem mudança comportamental ainda — só prep de schema e utilitários.

Escopo

Schema Simulado — acréscimos

@Prop({ required: false, default: null })
public disponivelDe?: Date | null;

@Prop({ required: false, default: null })
public disponivelAte?: Date | null;

Documentos legados mantêm null/null naturalmente (default do Mongoose).

Módulo availability.ts

Criar src/modules/simulado/availability.ts:

import { Simulado } from './schemas/simulado.schema';

export type AvailabilityStatus =
  | 'disponivel'        // bloqueado=false + dentro da janela (ou sem janela)
  | 'bloqueado'         // questões pendentes
  | 'antes_da_janela'   // bloqueado=false, mas now < disponivelDe
  | 'depois_da_janela'; // bloqueado=false, mas now > disponivelAte

export function isSimuladoAvailable(s: Simulado, now: Date = new Date()): boolean {
  if (s.bloqueado) return false;
  if (s.disponivelDe && now < s.disponivelDe) return false;
  if (s.disponivelAte && now > s.disponivelAte) return false;
  return true;
}

export function getAvailabilityStatus(s: Simulado, now: Date = new Date()): AvailabilityStatus {
  if (s.bloqueado) return 'bloqueado';
  if (s.disponivelDe && now < s.disponivelDe) return 'antes_da_janela';
  if (s.disponivelAte && now > s.disponivelAte) return 'depois_da_janela';
  return 'disponivel';
}

Duas funções puras. Fáceis de testar. Sem dependência de banco.

Índice composto em Mongo

Criar índice em simulados:

db.simulados.createIndex({
  categoria: 1,
  bloqueado: 1,
  disponivelDe: 1,
  disponivelAte: 1,
});

Migration Node/TypeScript one-off pra criar (ou via SimuladoSchema.index(...) que TypeORM/Mongoose aplica no boot — checar padrão do projeto).

Critérios de aceitação

  • Documentos novos de Simulado nascem com disponivelDe: null e disponivelAte: null
  • Documentos legados podem ser lidos sem erro (defaults do Mongoose cobrem)
  • isSimuladoAvailable retorna:
    • false se bloqueado === true
    • false se agora antes de disponivelDe
    • false se agora depois de disponivelAte
    • true nos demais casos (incluindo null/null)
  • getAvailabilityStatus retorna corretamente os 4 valores possíveis nos cenários equivalentes
  • Índice composto criado em produção via migration
  • Build passa; testes unitários das duas funções cobrem todos os 8 cenários (bloqueado, antes, dentro, depois × sem janela / com janela)

Risco

Muito baixo. Prep puro, sem mudança de comportamento. Adição de campos nullable com defaults é retrocompatível.

Observações

  • Semântica das combinações: os 4 casos são naturalmente suportados pela função — null/null (sempre disponível), só de (abre a partir de X), só até (fecha em X), de + até (janela fechada). Sem custo extra de código.
  • Índice composto ajuda o Card 02 (getAvailable) a filtrar eficientemente. Sem ele, scan de coleção em queries com filtro de janela.

Referências

  • Doc principal: docs/simulado-janela-disponibilidade.md §5 (modelo de dados) e §9 passos 1-2

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions