Core Docs
Backend

Recrutamento (Candidato, Vaga, Candidatura)

O núcleo do sistema — candidatos, vagas e o fluxo de candidatura entre eles.

Três módulos formam o pipeline de recrutamento: candidate, vacancy e application. Uma Vaga recebe Candidaturas de Candidatos; a candidatura é quem carrega o status do processo seletivo.

Candidato (candidate)

Entidade: CandidateEntity — estende BaseEntity (soft delete).

Campos principais: name, email (único), cpf (único), phoneNumber, position, birthDate, hasExperience, hasDriverLicense + driverLicenseType (A–E), hasChildren + childrenCount, maritalStatus (SOLTEIRO/CASADO/DIVORCIADO/VIUVO), gender (M/F), educationLevel (FUNDAMENTAL / ENSINO_MEDIO_INCOMPLETO / ENSINO_MEDIO_COMPLETO / SUPERIOR), status, inTalentPool, restricted, restrictionObservation (motivo obrigatório quando restricted = true) e address (value object embutido).

Máquina de estados (status)

AVAILABLE ──enteredProcess()──▶ IN_PROCESS ──allocate()──▶ ALLOCATED
    ▲                               │
    └───────backToAvailable()───────┘

qualquer estado ──restrict()──▶ RESTRICTED ──unrestrict()──▶ AVAILABLE
  • Só é possível allocate() se o candidato não estiver RESTRICTED.
  • restrict() marca restricted = true e muda o status para RESTRICTED.
  • Ao restringir um candidato, restrictionObservation deve informar o motivo da restrição; ao remover a restrição, esse campo é limpo.
  • Candidatos restritos ainda podem ser vinculados a vagas, mas o frontend deve exibir tag/alerta e pedir confirmação antes de criar a candidatura.
  • unrestrict() remove a restrição e retorna o candidato para AVAILABLE.

Endpoints (/gnoqcore/v1/candidate)

MétodoRotaPermissão
POST/candidate:create
GET/{id}, /email/{email}, /cpf/{cpf}, / (lista)candidate:read
PUT/{id}candidate:update
PATCH/{id}/restorecandidate:update
DELETE/{id}/trash, /{id}/forcecandidate:delete

Vaga (vacancy)

Entidades: VacancyEntity (estende BaseEntity) + VacancyDetailsEntity (um-para-um, dados específicos por motivo de abertura).

Campos principais: motive (ACCOUNT_EXPANSION / ABSENCE / BREAK / SUBSTITUTION / TEMPORARY), client / clientUnit (opcionais — uma vaga pode estar ligada a um cliente direto ou a uma unidade), state, city, openingDate, startDate, workload, position, hiringType, serviceType, vehicleType, approvalStatus (PENDING/APPROVED/REJECTED), status (OPEN/BEHIND_SCHEDULE/FILLED/CLOSED), salary e campos de benefício (feedingType/feedingValue, fuelValue, rentalValue, communicationValue, hazardPay, medicalPlan, dentalPlan), roadmapImageUrl (imagem enviada ao Supabase Storage, ver abaixo).

VacancyDetailsEntity guarda coveragePeriod (obrigatório para ABSENCE/BREAK) e substituteCompleteName / substituteRegistration (obrigatórios para SUBSTITUTION) — validado em validate() de acordo com o motive.

Máquina de estados (status + approvalStatus)

  • Vagas com motive = ACCOUNT_EXPANSION nascem com approvalStatus = PENDING e precisam ser approve()adas ou reject()adas (permissão vacancy:approval — é o fluxo da tela Aprovação de Vagas no frontend). Essa decisão é permitida enquanto a vaga estiver OPEN ou BEHIND_SCHEDULE. Qualquer outro motivo já nasce APPROVED.
  • markAsBehindSchedule(): OPEN → BEHIND_SCHEDULE, disparado automaticamente ~3 dias antes do startDate.
  • fill(): OPEN/BEHIND_SCHEDULE + APPROVEDFILLED.
  • close(): OPEN/BEHIND_SCHEDULECLOSED (idempotente).
  • reopen(): CLOSED → OPEN, só é permitido em até 12 dias após o fechamento — depois disso lança VacancyReopenPeriodExpiredException.

Endpoints (/gnoqcore/v1/vacancy)

MétodoRotaPermissão
POST/vacancy:create
GET/{id}, / (lista/filtros)vacancy:read
PUT/{id}vacancy:update
PATCH/{id}/approve, /{id}/rejectvacancy:approval
PATCH/{id}/roadmap-image (multipart)vacancy:update
PATCH/{id}/close, /{id}/reopen, /{id}/restorevacancy:update
DELETE/{id}/trashvacancy:deletebloqueado se houver candidaturas associadas
DELETE/{id}/forcevacancy:delete

Candidatura (application)

Entidade: ApplicationEntity — chave composta (vacancyId + candidateId, sem id próprio). É a entidade que conecta Candidato ↔ Vaga e carrega o andamento do processo seletivo.

Máquina de estados (status)

APPLIED ──approve()──▶ APPROVED ──hire()──▶ HIRED
   │                       │
   └─────reject()──────────┴─────reject()───▶ REJECTED
   │                       │
   └─────withdraw()────────┴─────withdraw()──▶ WITHDRAWN

                                           └──approve()──▶ APPROVED

HIRED e REJECTED são estados finais. WITHDRAWN permite reaprovação via approve(), para o caso em que o candidato desistiu e depois voltou ao processo. Cada transição publica um domain event (ApplicationCreatedEvent, ApplicationApprovedEvent, ApplicationHiredEvent, ApplicationRejectedEvent, ApplicationWithdrawnEvent).

Endpoints (/gnoqcore/v1/application)

MétodoRotaPermissão
POST/application:create
GET/vacancy/{vacancyId}/candidate/{candidateId}, / (lista paginada)application:read
PATCH.../approve, .../hire, .../reject, .../withdrawnapplication:update
DELETE/vacancy/{vacancyId}/candidate/{candidateId}application:delete

Observação: ao contrário dos outros módulos, Application não tem endpoint /force (hard delete) nem suporte a filtro deleted na listagem — ainda não segue o padrão completo de soft delete descrito em Soft Delete.

On this page