Core Docs
Backend

Eventos de Domínio e Jobs Agendados

Como o status do candidato reage automaticamente às mudanças de candidatura, e a rotina diária de vagas.

Eventos de domínio (application)

Cada transição de estado de ApplicationEntity (ver Recrutamento) publica um evento (ApplicationCreatedEvent, ApplicationHiredEvent, ApplicationRejectedEvent, ApplicationWithdrawnEvent), consumido por um listener próprio (ApplicationEventListener<T> do Micronaut) em application/application/listener/. É assim que o status do candidato fica sincronizado com o andamento das candidaturas sem o service de Application precisar conhecer as regras de Candidate.

EventoListenerO que faz
ApplicationCreatedEventApplicationCreatedEventListenerSe o candidato está AVAILABLE, muda pra IN_PROCESS
ApplicationHiredEventApplicationHiredEventListenerMarca o candidato como ALLOCATED, marca a vaga como FILLED, e rejeita automaticamente todas as outras candidaturas ativas daquela vaga (cada rejeição recalcula o status dos outros candidatos)
ApplicationRejectedEventApplicationRejectedEventListenerSe o candidato não tem mais nenhuma candidatura ativa, volta pra AVAILABLE
ApplicationWithdrawnEventApplicationWithdrawnEventListenerMesma lógica do rejeitado — recalcula o status do candidato

O "recalcular status" em comum usa applicationRepository.existsActiveApplicationForCandidate(id) — uma query dedicada, sem carregar a coleção inteira de candidaturas em memória.

Efeito colateral importante: contratar um candidato numa vaga (hire()) rejeita silenciosamente todos os outros candidatos em processo naquela mesma vaga — não é preciso rejeitar manualmente cada um.

Job agendado: fechamento por atraso (vacancy)

VacancySchedule (vacancy/application/service/VacancySchedule.java) roda todo dia à meia-noite (@Scheduled(cron = "0 0 0 * * *")):

@Scheduled(cron = "0 0 0 * * *")
@Transactional("default")
public void markVacanciesAsBehindSchedule() {
    List<VacancyEntity> openVacancies = vacancyRepository.findAllByStatusAndDeletedAtIsNull(VacancyStatusEnum.OPEN);
    openVacancies.forEach(vacancy -> vacancy.markAsBehindSchedule(LocalDate.now()));
}

Ele varre todas as vagas OPEN e chama markAsBehindSchedule() — que só efetivamente muda o status se a startDate estiver a ≤3 dias (ver a máquina de estados em Recrutamento). É a única tarefa agendada do sistema hoje.

On this page