Ir al contenido

Desempeño

El módulo cubre el flujo de autoservicio de evaluación de desempeño del usuario autenticado: ver las campañas activas en las que participa (como autoevaluado, jefe, par, cliente interno o evaluador de un colaborador), responder los formularios que le corresponden, guardar avances parciales, enviar la evaluación final, y consultar su historial de evaluaciones junto con el informe de resultados y el feedback recibido.

Acciones cubiertas:

  • Ver campañas de evaluación activas en las que el usuario participa (como evaluado o como evaluador).
  • Ver el detalle de una campaña (secciones habilitadas, tipo de evaluación).
  • Ver la lista de personas que el usuario debe evaluar dentro de una campaña (autoevaluación, jefe, pares, colaboradores a cargo, cliente interno, según cómo esté diseñada la campaña).
  • Responder el formulario de evaluación (funciones, competencias, condiciones organizacionales, filosofía, valores, potencial, comentarios) y guardarlo de forma parcial o final.
  • Ver el historial de evaluaciones propias, filtrado por año.
  • Ver el informe final de una evaluación terminada y el feedback publicado por el jefe.
  • Acusar recibo del feedback recibido.

Prerrequisitos:

  • El usuario debe estar autenticado y el x-tenant-id debe coincidir con su tenant (ver Convenciones).
  • Guardar progreso (PATCH .../save), ver historial y ver el informe requieren que el tenant tenga configurados sus parámetros generales — el backend rechaza estas llamadas si el tenant no los tiene (RequiresTenantParameters).
  • Las campañas tipo EM (Evaluación de MRL) quedan excluidas del listado de personas a evaluar (GET /me/evaluation/{id}/type/{abbreviation}), sin importar qué abbreviation se pida — el backend las filtra explícitamente. Si una campaña EM aparece en GET /me/evaluation, la app no podrá construir su roster con este flujo.
sequenceDiagram
    participant App as App móvil
    participant API as th-core-api

    Note over App,API: Lista de campañas activas
    App->>API: GET /me/evaluation
    API-->>App: campañas activas del usuario

    Note over App,API: Usuario abre una campaña
    App->>API: GET /me/evaluation/:id/details
    API-->>App: detalle + evaluationType.abbreviation + secciones habilitadas

    Note over App: abbreviation = ED (Desempeño) o similar -> ir al roster<br/>abbreviation = OB (Objetivos) -> flujo fuera de alcance
    App->>API: GET /me/evaluation/:id/type/:abbreviation
    API-->>App: personas a evaluar (autoevaluación, jefe, pares, colaboradores) con estado y accion requerida

    Note over App,API: Usuario elige a quién evaluar y empieza el formulario
    App->>API: GET /me/evaluation/content/all
    API-->>App: contenido dinámico del formulario según la configuración de la campaña

    Note over App,API: El usuario guarda avance en cualquier momento
    App->>API: PATCH /me/evaluation/:evaluationId/username/:usernameEvaluated/save
    Note over App: metadata.isFinal = false -> guardado parcial

    Note over App,API: Al completar todas las secciones, enviar
    App->>API: PATCH /me/evaluation/:evaluationId/username/:usernameEvaluated/save
    Note over App: metadata.isFinal = true -> envío final
    App->>API: GET /me/evaluation/:id/type/:abbreviation
    API-->>App: refresco del roster

    Note over App,API: Historial y resultados
    App->>API: GET /me/evaluation/history/years
    API-->>App: años con evaluaciones
    App->>API: GET /me/evaluation/history
    API-->>App: historial de evaluaciones propias

    Note over App,API: Si la evaluación terminada permite ver informe
    App->>API: GET /me/evaluation/:evaluationId/report
    API-->>App: informe final, incluye feedback del jefe si fue publicado

    Note over App,API: Si el jefe publicó feedback y aún no fue confirmado
    App->>API: PATCH /me/evaluation/:evaluationId/report/feedback/acknowledge
    API-->>App: confirmación

Campañas de evaluación activas en las que participa el usuario autenticado (como evaluado o como evaluador de alguien más).

Query params:

Param Tipo Obligatorio Enum Descripción
abbreviation string No EvaluationTypeAbbreviationEnum: PP, ED, PO, OB, EM Filtra a un solo tipo de evaluación.

Response — array de:

Campo Tipo Descripción
id number Id de la campaña de evaluación.
name string Nombre de la campaña.
evaluationTypeId number Id del tipo de evaluación.
evaluationType array [{ id, abbreviation }] — ver enum de tipos en Lógica de cliente.
periodId / periodMonth / periodYear number Período al que pertenece la campaña.
startDate / endDate date Vigencia de la campaña.
form string Código de formato interno ('1' horizontal, '2' vertical, '3' escala por conducta) — no confundir con el format de texto (HORIZONTAL/VERTICAL) que trae el informe final.
status enum EvaluationStatusEnum Estado de la campaña (ver tabla en Lógica de cliente).
maxScaleValue number Valor máximo de la escala de calificación.
instructions string | null Instrucciones HTML de la campaña, si las tiene.
hasResponsibilitiesConfigured boolean El tenant tiene habilitado el cumplimiento de responsabilidades para esta campaña.
hasFunction, hasObjective, hasCompetency, hasCondition, hasPhilosophy, hasValue, hasPotential, hasQuestions, hasResponses enum 'S' | 'N' Qué secciones tiene habilitadas la campaña. La app no necesita usarlos para armar el formulario — GET /me/evaluation/content/all ya devuelve sólo las secciones que aplican — pero sirven para mostrar un resumen rápido en la card.
weightCompetency, weightCondition, weightFunction, weightObjective, weightPhilosophy, weightValue, weightPotential, weightQuestions, weightResponses number Peso de cada sección en el puntaje final. Uso informativo; el cálculo lo hace el backend.
[
{
"id": 4102,
"name": "Evaluación de Desempeño 2026 - Semestre 1",
"evaluationTypeId": 2,
"evaluationType": [{ "id": 2, "abbreviation": "ED" }],
"periodId": 18,
"periodMonth": 6,
"periodYear": 2026,
"startDate": "2026-06-01T00:00:00.000Z",
"endDate": "2026-07-31T23:59:59.000Z",
"form": "1",
"status": "A",
"maxScaleValue": 5,
"instructions": null,
"hasResponsibilitiesConfigured": false,
"hasFunction": "S",
"hasObjective": "S",
"hasCompetency": "S",
"hasCondition": "N",
"hasPhilosophy": "N",
"hasValue": "N",
"hasPotential": "N",
"hasQuestions": "N",
"hasResponses": "N"
}
]

Sin errores específicos adicionales a los comunes.

Detalle completo de una campaña puntual — se usa principalmente para leer evaluationType.abbreviation y decidir a qué pantalla navegar, y para conocer los flags de configuración antes de entrar al roster.

Path param: id (number).

Response: mismos campos que GET /me/evaluation, más:

Campo Tipo Descripción
evaluationUsers array Todas las filas de evaluación asociadas a la campaña (evaluado, evaluador, relación, estado). En autoservicio normalmente no se recorre esta lista directamente — para eso está el endpoint paginado GET /me/evaluation/{id}/type/{abbreviation} — pero el campo viene presente.
hasStrategicObjective boolean true si la campaña tiene un objetivo estratégico asociado (strategicObjectivePeriodId > -1).

Sin errores específicos adicionales a los comunes.

Lista paginada de las personas que el usuario autenticado debe evaluar dentro de la campaña, con su estado y qué acción falta. abbreviation es el evaluationType.abbreviation de la propia campaña (obtenido en /details), no un valor libre.

Query params:

Param Tipo Obligatorio Descripción
page number No Página (default 1).
limit number No Ítems por página (default 10).
includeAutoEvaluations boolean No (default false) Si es false, oculta la fila donde el evaluador es igual al evaluado (tu propia autoevaluación). El frontend de referencia siempre envía true para mostrarla junto al resto.

Response:

{
"items": [ /* ver tabla de campos abajo */ ],
"meta": {
"totalItems": 4,
"itemCount": 4,
"itemsPerPage": 10,
"totalPages": 1,
"currentPage": 1,
"pendingCount": 2
}
}

Campos de cada item (entidad casi cruda — este endpoint no tiene un DTO de respuesta formal, a diferencia del resto del módulo):

Campo Tipo Descripción
username string Usuario evaluado en esta fila.
evaluator string Usuario evaluador (el autenticado, salvo casos administrativos).
evaluationId number Id de la campaña.
relationId number Relación del evaluador respecto al evaluado — ver tabla RelationEnum en Lógica de cliente.
relation object { id, name } — nombre legible de la relación.
status enum EvaluationUserStatusEnum Estado de esta evaluación puntual (ver tabla en Lógica de cliente).
user object { username, name, lastName, avatar, position: { id, name } } — datos del evaluado.
userAutoevaluationStatus enum | null Sólo presente si relationId es 1 (Jefe) o 6 (Gerente Funcional): estado de la autoevaluación del evaluado, para saber si ya puede evaluarlo.
actionRequired object | null { key, defaultLabel } si hay una acción bloqueante antes de poder calificar — ver tabla en Lógica de cliente. null si puede evaluar directamente.
{
"items": [
{
"username": "jperez",
"evaluator": "jperez",
"evaluationId": 4102,
"relationId": 5,
"relation": { "id": 5, "name": "Autoevaluación" },
"status": "F",
"user": {
"username": "jperez",
"name": "Juan",
"lastName": "Pérez",
"avatar": "jperez.png",
"position": { "id": 31, "name": "Analista de Nómina" }
},
"userAutoevaluationStatus": null,
"actionRequired": null
},
{
"username": "mrojas",
"evaluator": "jperez",
"evaluationId": 4102,
"relationId": 3,
"relation": { "id": 3, "name": "Pares" },
"status": "A",
"user": {
"username": "mrojas",
"name": "María",
"lastName": "Rojas",
"avatar": "mrojas.png",
"position": { "id": 40, "name": "Analista de Nómina" }
},
"userAutoevaluationStatus": null,
"actionRequired": null
}
],
"meta": {
"totalItems": 2,
"itemCount": 2,
"itemsPerPage": 10,
"totalPages": 1,
"currentPage": 1,
"pendingCount": 1
}
}

Sin errores específicos adicionales a los comunes.

GET /me/evaluation/{id}/type/{abbreviation}/user

Sección titulada «GET /me/evaluation/{id}/type/{abbreviation}/user»

Variante singular del endpoint anterior: devuelve la fila de evaluación del propio usuario autenticado (evaluado = evaluador = usuario actual) para esa campaña y tipo, sin paginar.

Path params: id (number), abbreviation (EvaluationTypeAbbreviationEnum).

Response: un solo objeto con la misma forma que un item de GET /me/evaluation/{id}/type/{abbreviation}.

Errores específicos:

Código Cuándo ocurre
404 La evaluación no existe o el usuario no está autorizado a verla.

Devuelve el contenido dinámico del formulario de evaluación — funciones, objetivos, competencias, condiciones organizacionales, filosofía, valores, potencial, preguntas — ya filtrado según qué secciones tiene habilitadas la campaña y la relación del evaluador. Es el endpoint que carga la pantalla de responder evaluación.

Query params:

Param Tipo Obligatorio Descripción
evaluationId number Funcionalmente sí Id de la campaña.
username string Funcionalmente sí Usuario evaluado (viene del roster, no siempre es el usuario autenticado).
positionId number Funcionalmente sí Cargo del evaluado, tomado del roster.
evaluationId, relationship number Funcionalmente sí relationId de la fila del roster que el usuario eligió evaluar.
userAutoevaluationStatus string No Estado de autoevaluación del evaluado, tomado del roster — se usa para decidir si mostrar la referencia de autoevaluación.

Response (resumen; la forma completa es extensa y varía según qué secciones tenga la campaña):

Campo Tipo Descripción
evaluation.id / .name Si vienen ausentes, la campaña/parámetros no se resolvieron — ver nota de errores abajo.
evaluation.evaluationType object { id, abbreviation }.
evaluation.configuration object Flags hasFunction/hasObjective/hasCompetency/hasQuestions/hasQuestionsPerformance/hasCondition/hasPhilosophy/hasValue/hasPotential ('S'/'N'), más activeisNotObserved, activeFlowControl, activeAutomaticVerification, registeredUserConfig y format (código '1'/'2'/'3', igual convención que el campo form de la campaña).
scales.mainScale / .objectiveScale / .strategyScale array Cada valor: { id, idScale, valueName, shortValueName, value, valueOrder, status }. Es la escala de calificación configurable por tenant.
components.functions / .objectives / .competencies / .behaviors / .philosophies / .values / .questions / .questionsPerformance / .potential / .responsibilities array Sólo vienen pobladas las secciones habilitadas para esta relación; el resto llega como []. Cada item trae al menos id, name, result (calificación ya guardada, si existe) y resultAutoevaluation (referencia de la autoevaluación, si aplica).
metadata.evaluator / .evaluated / .positionId / .relationship / .status Eco de los parámetros de la request más el estado actual.
metadata.totalItems object { functions, objectives, competencies, behaviors, philosophies, values, potential, responsibilities } — cantidad de ítems por sección, usado para calcular el progreso.
general.observation / .secondObservation string Comentarios generales ya guardados.
general.observationAutoevaluation / .secondObservationAutoevaluation string Comentarios de la autoevaluación, como referencia (si aplica).
general.isRecommended 'S' | 'N' Recomendación de aprobación (uso administrativo).
weights.* number | null Peso de cada sección en el puntaje final de esta evaluación puntual.
{
"evaluation": {
"id": 4102,
"name": "Evaluación de Desempeño 2026 - Semestre 1",
"evaluationType": { "id": 2, "abbreviation": "ED" },
"configuration": {
"hasFunction": "S",
"hasObjective": "S",
"hasCompetency": "S",
"hasCondition": "N",
"hasPhilosophy": "N",
"hasValue": "N",
"hasPotential": "N",
"hasQuestions": "N",
"hasQuestionsPerformance": "N",
"activeisNotObserved": "S",
"activeFlowControl": "S",
"activeAutomaticVerification": "S",
"registeredUserConfig": "U",
"format": "1"
}
},
"scales": {
"mainScale": [
{ "id": 1, "idScale": 3, "valueName": "Insuficiente", "shortValueName": "1", "value": 1, "valueOrder": 1, "status": "A" },
{ "id": 5, "idScale": 3, "valueName": "Sobresaliente", "shortValueName": "5", "value": 5, "valueOrder": 5, "status": "A" }
],
"objectiveScale": [],
"strategyScale": []
},
"components": {
"functions": [
{ "id": 812, "name": "Procesar nómina quincenal", "description": "", "weight": 40, "result": 0, "resultAutoevaluation": 4 }
],
"objectives": [],
"competencies": [],
"behaviors": [],
"philosophies": [],
"values": [],
"questions": [],
"questionsPerformance": [],
"potential": [],
"responsibilities": []
},
"metadata": {
"evaluator": "mrojas",
"evaluated": "jperez",
"positionId": 31,
"relationship": 3,
"status": "A",
"totalItems": { "functions": 1, "objectives": 0, "competencies": 0, "behaviors": 0, "philosophies": 0, "values": 0, "potential": 0, "responsibilities": 0 }
},
"general": { "observation": "", "secondObservation": "" },
"weights": { "objectives": null, "functions": 100, "specificCompetencies": null, "organizationalCompetencies": null, "philosophy": null, "values": null, "potential": null, "finalComments": null, "responsibilities": null }
}

Errores:

No hay excepciones 4xx confirmadas por parámetros faltantes o evaluationId inexistente — en ese caso la respuesta vuelve igual (200) con evaluation ausente y todos los arrays de components vacíos. La app debe verificar que evaluation?.id venga presente antes de renderizar el formulario, en vez de esperar un error.

Código Cuándo ocurre
400 El control de flujo secuencial de la campaña bloquea esta evaluación en este momento (mismo criterio que el actionRequired del roster — no debería pasar si la app ya ocultó el botón, pero el backend lo revalida).

PATCH /me/evaluation/{evaluationId}/username/{usernameEvaluated}/save

Sección titulada «PATCH /me/evaluation/{evaluationId}/username/{usernameEvaluated}/save»

Guarda el avance de una evaluación puntual (parcial) o la envía como final.

Path params: evaluationId (number), usernameEvaluated (string — el evaluado, no necesariamente el usuario autenticado).

Body (SaveEvaluationProgressDto):

Campo Tipo Obligatorio Descripción
general.observation string No Comentario general.
general.secondObservation string No Áreas de mejora / segundo comentario.
general.isRecommended 'S' | 'N' No Recomendación de aprobación (uso administrativo).
metadata.positionId number Cargo del evaluado.
metadata.isFinal boolean No (default false) false = guardado parcial (la fila queda en A/Activa). true = envío final (la fila pasa a F/Finalizada).
components.functions / .objectives / .responsibilities / .questions / .questionsPerformance / .potential array No Formato completo: [{ id, obtainedLevel }] (objetivos y responsabilidades además admiten observation, file, approvalStatus).
components.competencies / .behaviors / .philosophies / .values array No Formato completo (horizontal): [{ competency: { id, competencyBehaviors: [{ id, obtainedLevel }] } }].
components.competenciesRatings / .behaviorsRatings / .philosophiesRatings / .valuesRatings / .potentialRatings object No Formato simplificado (vertical): mapa { [id]: obtainedLevel }. El backend lo transforma internamente a la forma completa — usa uno de los dos formatos según evaluation.configuration.format de content/all, nunca ambos para la misma sección.
{
"general": {
"observation": "Buen desempeño en el período, cumplió los objetivos principales.",
"secondObservation": "Mejorar tiempos de respuesta en solicitudes urgentes."
},
"components": {
"functions": [
{ "id": 812, "obtainedLevel": 4 }
],
"objectives": [],
"responsibilities": [],
"questions": [],
"questionsPerformance": []
},
"metadata": {
"positionId": 31,
"isFinal": true
}
}

Response: 200, sin cuerpo relevante (confirmación de guardado).

Errores específicos:

Código Cuándo ocurre
400 Falta evaluator, evaluationId, evaluated o el body data.
400 Todas las filas de evaluación de este usernameEvaluated/evaluador ya están en estado F (Finalizada) — no se puede reenviar.
404 La campaña (evaluationId) no existe.
404 No hay filas de evaluación para ese usernameEvaluated con este evaluador en esta campaña.

Historial de evaluaciones (de todo tipo) del usuario autenticado, con métricas de progreso y resultado.

Query params:

Param Tipo Obligatorio Descripción
periodId number No Filtra por período.
evaluationTypeId number No Filtra por tipo de evaluación.
year number No Filtra por año del período.
username string No Omitir en self-service — sólo se usa en la ficha de administración de un colaborador. Sin él, se consulta el usuario autenticado.

Response — array de:

Campo Tipo Descripción
evaluationId / evaluationName Identificador y nombre de la campaña.
periodId / periodYear Período.
evaluationType object { id, name, abbreviation }.
startDate / endDate date Vigencia.
progress number Porcentaje de avance (0-100).
completedCount / totalCount number Evaluadores que ya terminaron vs. total asignado.
score number | null Puntaje final. null si aún no hay puntaje evaluable o si es una evaluación de Líder Multiplicador (isLeadershipMultiplier).
developmentLevel object | null { id, name, color } — nivel de desarrollo (semáforo).
status string Estado de la campaña.
totalObjectives / evaluatedObjectives number Objetivos asignados vs. evaluados (fuera de alcance detallar el flujo de objetivos, pero el dato viene en el historial).
objectiveCompliance number | null % de cumplimiento promedio de los objetivos evaluados.
isPublished boolean El registro de evaluación del usuario está marcado como publicado.
isFinished boolean La evaluación llegó a 100% de avance.
canViewReport boolean Habilita el botón “Ver informe” — sólo mostrarlo si isFinished && canViewReport.
canViewObjectives boolean Fuera de alcance (módulo de objetivos).
isLeadershipMultiplier boolean Evaluación de Líder Multiplicador — no tiene score/developmentLevel global, esas columnas se muestran vacías.
[
{
"evaluationId": 3980,
"evaluationName": "Evaluación de Desempeño 2025 - Semestre 2",
"periodId": 17,
"periodYear": 2025,
"evaluationType": { "id": 2, "name": "Evaluación de Desempeño", "abbreviation": "ED" },
"startDate": "2025-12-01T00:00:00.000Z",
"endDate": "2026-01-15T23:59:59.000Z",
"progress": 100,
"completedCount": 4,
"totalCount": 4,
"score": 86.5,
"developmentLevel": { "id": 3, "name": "Cumple lo esperado", "color": "#22C55E" },
"status": "F",
"totalObjectives": 3,
"evaluatedObjectives": 3,
"objectiveCompliance": 92.1,
"isPublished": true,
"isFinished": true,
"canViewReport": true,
"canViewObjectives": true,
"isLeadershipMultiplier": false
}
]

Sin errores específicos adicionales a los comunes.

Años disponibles en el historial del usuario, para armar el filtro de año.

Sin query params en self-service (el parámetro username existe pero es sólo para la ficha de administración — omitirlo).

Response: number[], por ejemplo [2024, 2025, 2026].

Sin errores específicos adicionales a los comunes.

Informe final de una evaluación terminada: puntajes por sección, resultado consolidado, nivel de desarrollo y feedback.

Path param: evaluationId (number).

Query params:

Param Tipo Obligatorio Descripción
username string No Omitir en self-service — sin él, se devuelve el informe del usuario autenticado.
showByEvaluator boolean No (default false) Incluye el desglose de puntajes por tipo de evaluador (autoevaluación, jefe, pares, etc.) en cada sección.

Response (resumen — la forma completa es extensa y varía según qué secciones tenga habilitada la evaluación):

Campo Tipo Descripción
evaluation object Metadata: { id, name, type, period, startDate, endDate, format, isAnonymous }. format acá viene como texto ('HORIZONTAL' / 'VERTICAL'), a diferencia del código numérico de content/all.
evaluatedUser object { username, fullName, identification, position, department, avatar }.
configuration object Qué secciones están habilitadas (hasFunction, hasCompetency, hasBehavior, hasObjective, hasResponsibility, hasEnterpriseObjective, hasLeadershipMultiplier, hasPhilosophy, hasValue, hasPotential) y sus pesos.
keyMetrics.items array Métricas para el resumen ejecutivo: { key, name, percentage, developmentLevel, weight, isEnabled } por sección.
sections.* object Una clave por sección habilitada (functions, competencies, behaviors, objectives, responsibilities, enterpriseObjectives, specificCompetencies, organizationalCompetencies, leadershipMultiplier), cada una con su consolidated (average, percentage, items[]) y, si se pidió showByEvaluator=true, byEvaluator[].
finalResult object { score, scaleValue, pointsScore?, developmentLevel?, developmentScale?, isAccepted, acceptedDate? } — resultado consolidado.
feedback object Ver tabla de feedback más abajo.
evaluators array { evaluator, evaluatorName, relationId, relationName, status, evaluationDate, avatar } — quiénes participaron como evaluadores.

feedback (relevante para el flujo de acuse de recibo):

Campo Tipo Descripción
sentFeedback string Feedback que el jefe escribió/publicó para el evaluado.
receivedFeedback string Comentario del evaluado en respuesta (queda vacío hasta que acusa recibo).
isFeedbackPublished boolean El jefe publicó el feedback. Mostrar el bloque de feedback sólo si es true.
isFeedbackAcknowledged boolean El evaluado ya acusó recibo. Mientras sea false y isFeedbackPublished sea true, mostrar el formulario de acuse.
byEvaluator array { relationId, relationName, comments: string[] } — observaciones de cada evaluador, agrupadas por relación.
{
"evaluation": {
"id": 3980,
"name": "Evaluación de Desempeño 2025 - Semestre 2",
"type": { "id": 2, "name": "Evaluación de Desempeño", "abbreviation": "ED" },
"period": { "id": 17, "year": 2025 },
"startDate": "2025-12-01T00:00:00.000Z",
"endDate": "2026-01-15T23:59:59.000Z",
"format": "HORIZONTAL",
"isAnonymous": false
},
"evaluatedUser": {
"username": "jperez",
"fullName": "Juan Pérez",
"identification": "0102030405",
"position": { "id": 31, "name": "Analista de Nómina" },
"department": { "id": 6, "name": "Recursos Humanos" },
"avatar": "jperez.png"
},
"finalResult": {
"score": 86.5,
"scaleValue": 4,
"developmentLevel": { "id": 3, "name": "Cumple lo esperado", "color": "#22C55E" },
"isAccepted": true,
"acceptedDate": "2026-01-16T10:05:00.000Z"
},
"feedback": {
"sentFeedback": "Excelente cierre de período, sigue así en el control de tiempos.",
"receivedFeedback": "",
"isFeedbackPublished": true,
"isFeedbackAcknowledged": false
},
"evaluators": [
{ "evaluator": "jperez", "evaluatorName": "Juan Pérez", "relationId": 5, "relationName": "Autoevaluación", "status": "F", "evaluationDate": "2026-01-10T09:00:00.000Z", "avatar": "jperez.png" }
]
}

Errores específicos:

Código Cuándo ocurre
404 La evaluación no existe o el usuario autenticado no está autorizado a verla.

PATCH /me/evaluation/{evaluationId}/report/feedback/acknowledge

Sección titulada «PATCH /me/evaluation/{evaluationId}/report/feedback/acknowledge»

El empleado acusa recibo del feedback publicado por su jefe.

Path param: evaluationId (number).

Body (AcknowledgeFeedbackDto):

Campo Tipo Obligatorio Descripción
comment string No Comentario opcional del empleado sobre el feedback recibido.
{
"comment": "Gracias por el feedback, voy a trabajar en los tiempos de respuesta."
}

Response: { "success": true }.

Errores específicos:

Código Cuándo ocurre
400 No hay feedback publicado para acusar recibo todavía (isFeedbackPublished es false).

Variante de GET /me/evaluation que devuelve, además de los mismos campos, evaluationUsers[] embebido en cada campaña (igual forma que en /details) y hasStrategicObjective.

Sin query params.

Valor Significado Texto sugerido
A Activa Activa
I Inactiva Inactiva
R Registrada Registrada
F Finalizada Finalizada
X Eliminada — (excluir de listados)

La card de campaña en el listado usa este status para el badge Activa/Inactiva, pero además calcula en el cliente si endDate < fecha actual para mostrar “Finalizada” superpuesto al badge — no es un valor que devuelva el backend, es una regla del cliente sobre endDate.

Estados de una fila de evaluación (EvaluationUserStatusEnum)

Sección titulada «Estados de una fila de evaluación (EvaluationUserStatusEnum)»
Valor Significado backend Texto sugerido en el roster
A Activa (pendiente de calificar) Pendiente
P En proceso Pendiente
F Finalizada Completada
V En validación Pendiente
C En calibración Pendiente
N Rechazada Pendiente
R Registrada Pendiente

El roster simplifica todo lo que no sea F a “Pendiente” con el botón “Empezar evaluación”, salvo que actionRequired esté presente (ver siguiente tabla), en cuyo caso se reemplaza el botón por el texto de la acción bloqueante.

Acción requerida antes de poder calificar (actionRequired.key)

Sección titulada «Acción requerida antes de poder calificar (actionRequired.key)»
Valor Texto sugerido Cuándo aparece
selfEvaluationPending Autoevaluación pendiente El control de flujo de la campaña está activo y el evaluado todavía no terminó su propia autoevaluación.
immediateManagerPending Pendiente Jefe Inmediato Evaluación de tipo Objetivo donde falta la acción del jefe inmediato antes de continuar.

Si actionRequired es null, el botón “Empezar evaluación” está habilitado.

Relación evaluador → evaluado (RelationEnum)

Sección titulada «Relación evaluador → evaluado (RelationEnum)»
Valor (relationId) Significado
1 Jefe Inmediato
2 Colaborador
3 Pares
4 Cliente Interno
5 Autoevaluación
6 Gerente Funcional

Tipos de evaluación (EvaluationTypeAbbreviationEnum)

Sección titulada «Tipos de evaluación (EvaluationTypeAbbreviationEnum)»
Valor Significado Navegación desde la card
PP Evaluación de Periodo de Prueba /performance/:id (genérica)
ED Evaluación de Desempeño /performance/:id/evaluations (roster de este documento)
PO Evaluación de Potencial de Liderazgo /performance/:id (genérica)
OB Registro y Aprobación de Objetivos Fuera de alcance — ruta distinta según registeredUserConfig de la campaña.
EM Evaluación de MRL Excluida del roster (ver Prerrequisitos); no navegable con este flujo.

GET /me/evaluation/content/all sólo devuelve pobladas las secciones habilitadas para la relación del evaluador actual; el resto llega como arrays vacíos. La app debe ocultar cualquier sección cuyo array venga vacío, sin asumir que todas las evaluaciones tienen todas las secciones.

  • Formato vertical (configuration.format === '2'): enviar los mapas simplificados (competenciesRatings, behaviorsRatings, philosophiesRatings, valuesRatings, potentialRatings) en el save, no las estructuras anidadas.
  • Formato horizontal ('1' o '3'): enviar las estructuras completas (competencies, behaviors, philosophies, values con competencyBehaviors anidados).
  • La calificación -1 significa “No observado” y sólo es una opción válida si configuration.activeisNotObserved === 'S'.
  • La escala (scales.mainScale) puede ser numérica o de texto — si todos los valueName son numéricos, tratarla como escala numérica; si no, como escala de opciones con etiqueta.

Mostrar el valor de autoevaluación (resultAutoevaluation en cada item, o general.observationAutoevaluation para comentarios) sólo cuando se cumplen las tres condiciones:

  1. configuration.activeAutomaticVerification === 'S'.
  2. La relación actual no es autoevaluación (relationship !== 5).
  3. metadata.userAutoevaluationStatus === 'F' (el evaluado ya finalizó su propia autoevaluación).
  • El progreso se calcula como ítems calificados / metadata.totalItems (suma de todas las secciones con datos).
  • El botón “Enviar” (envío final, isFinal: true) sólo se habilita cuando todas las secciones con ítems están completas — no sólo la sección visible en pantalla.
  • El botón “Guardar avance” (isFinal: false) está disponible en cualquier momento, aunque falten secciones.
  • Después de un envío final exitoso, volver al roster (GET /me/evaluation/{id}/type/{abbreviation}) para reflejar el nuevo estado.
  • Si el usuario reintenta guardar sobre una evaluación donde todas sus filas ya están F, el backend responde 400 — la app debería haber deshabilitado la acción antes de llegar a este punto (roster con status = F).

Historial: filtro por año y nivel de desarrollo

Sección titulada «Historial: filtro por año y nivel de desarrollo»
  • Poblar el selector de año con GET /me/evaluation/history/years; si el año actual no tiene datos, seleccionar por defecto el año más reciente que sí tenga (no forzar el año calendario actual).
  • El filtro “Nivel de desarrollo” (Cumple lo esperado / Por debajo de lo esperado / No evaluado) es una convención del cliente sobre score, no un campo del backend: score === null → “No evaluado”; score >= 70 → “Cumple lo esperado”; en cualquier otro caso → “Por debajo de lo esperado”. El umbral (70) es del cliente de referencia, no algo que confirme el backend — validar contra el criterio real de negocio antes de reutilizarlo.
  • Mostrar la acción “Ver informe” en el historial sólo si isFinished && canViewReport del item correspondiente.
  • Dentro del informe, mostrar el bloque de feedback sólo si feedback.isFeedbackPublished.
  • Si isFeedbackPublished && !isFeedbackAcknowledged, mostrar el formulario de acuse (comentario opcional + confirmación); tras PATCH .../acknowledge exitoso, refrescar el informe para que isFeedbackAcknowledged pase a true y el bloque quede de solo lectura.
  • Sin campañas activas: GET /me/evaluation devuelve [] — mostrar estado vacío (“No tienes evaluaciones activas”).
  • Roster vacío: GET /me/evaluation/{id}/type/{abbreviation} sin ítems — no debería ocurrir si la campaña apareció en el listado, pero si pasa, tratar como estado vacío, no como error.
  • Sin historial: GET /me/evaluation/history devuelve [] — mostrar estado vacío, ocultando los filtros de año/nivel salvo que existan años disponibles.
  • content/all sin evaluation: tratar como error de carga (no se pudo resolver el contenido del formulario) y no como campaña sin secciones.