Skip to content

Flujo de la empresa

9 casos del lado company_user: gestión de datos, vacantes, revisión de candidatos presentados, notas internas visibles para HUMAE, solicitud y confirmación de entrevistas.

Duración estimada: 25 minutos.

Gestión de equipo no disponible

La invitación de miembros al equipo de empresa está en desarrollo y no es parte del alcance actual de pruebas. Cada empresa opera con el usuario owner creado al registrarse.

Datos de empresa

TC-EMP-001 · Ver panel de empresa

Severidad: 🟠 Alta

Precondiciones: company_user logueado (ver Plan general)

Pasos:

  1. Nav → "Empresa" → "Mis vacantes" (o navegar directo a /me/empresa/vacantes)

Resultado esperado:

  • Header: título "Vacantes de mi empresa" + botón "Nueva vacante".
  • Si no hay vacantes: card con mensaje "Aún no has creado vacantes. Abre 'Nueva vacante' para empezar."
  • Si ya hay vacantes: cards con título, código, badge de estado, y fechas (creada / publicada / cierra), cada una clickable para detalle.

Variaciones:

  • company_user sin empresa asociada → UI muestra "Tu cuenta no está vinculada a una empresa".

TC-EMP-002 · Editar datos de la empresa

Severidad: 🟡 Media

Precondiciones: company_user con rol interno owner.

Pasos:

  1. Nav → "Empresa" → "Datos de empresa" (o /me/empresa)
  2. Botón "Editar datos"
  3. Cambiar nombre, descripción, industria, tamaño, sitio web, contacto
  4. Guardar

Resultado esperado:

  • PATCH /api/v1/me/company → 200.
  • UI refleja cambios sin recargar (cache invalidada).

Variaciones:

  • Subir nuevo logo → se guarda en storage/app/public/companies/{company_id}/....

Vacantes

TC-EMP-004 · Crear vacante como borrador

Severidad: 🔴 Crítica

Pasos:

  1. /me/empresa/vacantes → botón "Nueva vacante"
  2. Form con: título, descripción, responsabilidades, requisitos, beneficios, tipo de candidato requerido (Cualquiera/Empleado/Practicante), ubicación + remoto/híbrido, salario min/max, periodo, prioridad, fecha de cierre
  3. Dejar el selector "Tipo de candidato requerido" en su default (Cualquiera).
  4. Guardar.

Resultado esperado:

  • POST /api/v1/me/company/vacancies → 201.
  • Vacancy.state = borrador, code = HUM-YYYY-NNNN, slug autogenerado.
  • Vacancy.target_candidate_kind = 'any' por default.
  • Redirige a /me/empresa/vacantes/{id}.
  • Aparece en la lista con badge "Borrador" (sin badge de categoría porque es any).

Variaciones:

  • Sin título → 422 "Requerido".
  • salary_min > salary_max → validación cliente + backend (gte:salary_min).
  • target_candidate_kind = "banana" (manualmente por API) → 422 con errors.target_candidate_kind.

TC-EMP-004b · Crear vacante con target_candidate_kind = intern

Severidad: 🔴 Crítica (PDF cosasfaltanteshumae punto 2 / clasificación de vacantes)

Pasos:

  1. /me/empresa/vacantes → "Nueva vacante".
  2. Llenar título "Practicante de Calidad", descripción mínima.
  3. En "Tipo de candidato requerido" elegir Practicante.
  4. En "Área funcional" elegir Calidad.
  5. En "Mín. años experiencia" → 0; "Máx." → 1.
  6. Guardar y publicar (transición a activa).

Resultado esperado:

  • Vacancy.target_candidate_kind = 'intern'.
  • En el detalle (/me/empresa/vacantes/{id}), junto al estado, aparece un badge ámbar Practicante.
  • En /recruiter/vacantes/{id}/pipeline → click "Ver sugerencias" → la lista solo muestra candidatos con candidate_kind = intern con score alto en el eje categoría (25 pts cada uno).

Variaciones:

  • Editar la vacante después y cambiar a employee → al refrescar las sugerencias, los practicantes salen del top y entran los empleados.
  • Cambiar a any → vuelven a aparecer ambos kinds, con 60 % parcial (15 pts) en el eje categoría.

TC-EMP-005 · Publicar vacante

Severidad: 🔴 Crítica

Precondiciones: Vacante en borrador con campos mínimos.

Pasos:

  1. /me/empresa/vacantes/{id} → header con botón "Publicar".
  2. Clic.

Resultado esperado:

  • POST /api/v1/me/company/vacancies/{id}/transition con {to: "activa"} → 200.
  • state = activa, published_at = now().
  • Badge cambia a "Activa".
  • La vacante ahora visible para el reclutador en /recruiter/vacantes.

Variaciones:

  • Publicar ya publicada → 409 (transición inválida desde activa).

TC-EMP-006 · Cancelar vacante

Severidad: 🟠 Alta

Precondiciones: Vacante en estado no terminal.

Pasos:

  1. Detalle → botón "Cancelar"
  2. Dialog pide motivo opcional
  3. Confirmar

Resultado esperado:

  • state = cancelada, cancelled_at = now(), cancel_reason guardado.
  • UI bloquea edición del form (campos disabled).

Variaciones:

  • Cancelar vacante ya cancelada → 409.
  • company_user intenta to=en_busqueda → 403 (solo activa y cancelada desde empresa).

Candidatos presentados

TC-EMP-007 · Ver candidatos presentados a una vacante

Severidad: 🔴 Crítica

Precondiciones: Recruiter asignó y movió candidatos a presented (ver TC-REC-010).

Pasos:

  1. /me/empresa/vacantes/{id} → tab "Candidatos"

Resultado esperado:

  • GET /api/v1/me/company/vacancies/{id}/assignments → 200 con stages presented|interviewing|finalist|hired.
  • Lista de candidate cards (sin datos de contacto, sin email/teléfono) con foto, nombre, headline, years_of_experience, skills top-5, badge de stage.
  • NO se ven stages sourced|rejected|withdrawn.

TC-EMP-008 · Abrir panel de notas y añadir nota

Severidad: 🟠 Alta

Pasos:

  1. Tab "Candidatos" → una card → clic "Ver notas y dejar comentario"
  2. Escribir nota en textarea
  3. "Enviar nota"

Resultado esperado:

  • POST /api/v1/assignments/{id}/notes con body → 201.
  • Backend fuerza visibility = 'company' (aunque el cliente mande internal).
  • La nota aparece en el panel con badge "De la empresa".
  • El reclutador puede verla en su lado del pipeline.

Variaciones:

  • Body vacío → botón "Enviar nota" queda disabled.

TC-EMP-009 · Solicitar entrevista

Severidad: 🟠 Alta

Precondiciones: Vacante en con_candidatos_asignados o entrevistas_en_curso; asignación en un stage válido para entrevistas.

Pasos:

  1. Card del candidato → botón "Solicitar entrevista"
  2. Dialog: fecha y hora, modo (online/presencial/telefónica), meeting_url o location, duración
  3. Enviar

Resultado esperado:

  • POST /api/v1/interviews → 201.
  • Interview.state = propuesta, round = 1.
  • Notificaciones al candidato, owners/managers de la empresa, y al recruiter asignado.
  • En /me/entrevistas aparece como "Propuesta".

Variaciones:

  • Vacante en borrador → 409 "La vacante no está en un estado que admita entrevistas".
  • Otra empresa → 403.

TC-EMP-010 · Confirmar entrevista agendada por reclutador

Severidad: 🔴 Crítica

Precondiciones: Recruiter agendó (o reprogramó) una entrevista. Estado propuesta.

Pasos:

  1. Nav → "Empresa" → "Entrevistas" (o /me/entrevistas).
  2. Card de la entrevista en estado "Propuesta" → botón "Confirmar".

Resultado esperado:

  • POST /api/v1/interviews/{id}/confirm → 200.
  • Interview.state = confirmada.
  • InterviewConfirmedNotification (database + mail) al candidato, owners/managers de la empresa, y al recruiter de la asignación.
  • La card pasa al badge "Confirmada"; ya no aparece el botón "Confirmar" sino "Marcar realizada" (sólo recruiter) y "Cancelar" (ambos).

Variaciones:

  • Entrevista ya en confirmada → idempotente: el botón ya no aparece o, si se ataca el endpoint directo, devuelve la misma entrevista sin notificación duplicada.
  • Entrevista en estado terminal (realizada, cancelada, no_asisto) → 409 "La entrevista no puede confirmarse en este estado".
  • Otro company_user de otra empresa → 403.

TC-EMP-011 · Cancelar entrevista (con motivo opcional)

Severidad: 🟠 Alta

Precondiciones: Entrevista en propuesta o confirmada para una asignación de la propia empresa.

Pasos:

  1. /me/entrevistas → card de la entrevista → botón "Cancelar".
  2. Prompt de motivo (opcional, máx 500 chars) — ej. "Reagendaremos la próxima semana".
  3. Confirmar.

Resultado esperado:

  • POST /api/v1/interviews/{id}/cancel con { "reason": "…" } → 200.
  • Interview.state = cancelada (terminal). La asignación no cambia de stage automáticamente.
  • Si se pasó reason: se appendea a recruiter_feedback con prefijo [cancelado] para auditoría.
  • InterviewCancelledNotification (database + mail) al candidato, owners/managers de la empresa, y al recruiter de la asignación. El motivo viaja en la notificación.
  • La card desaparece del listado por defecto y aparece sólo si se filtra por estado "Cancelada".

Variaciones:

  • Sin motivo → cancelación aceptada; la notificación va sin reason.
  • Motivo > 500 chars → 422.
  • Entrevista en realizada / cancelada / no_asisto → 409 "La entrevista ya no puede cancelarse".
  • company_user de otra empresa → 403.

Después de cancelar

Si se quiere reprogramar, el flujo natural es proponer una nueva entrevista (TC-EMP-009) sobre la misma asignación — el round se incrementa automáticamente. La entrevista cancelada queda en histórico para auditoría.

Siguiente

Flujo del administrador →

Manual de usuario HUMAE · Uso interno