- REST API construida con Spring Boot 3.5.6 y Java 21 para gestionar plantillas de actividades, asignaciones, usuarios, roles y el historial de puntajes semanales del equipo. POM, GradingApplication
- Persistencia con JPA y MySQL, auditorías automáticas vía una entidad base compartida, y migraciones de base de datos con Flyway. POM, BaseEntity, JpaConfig
- Autenticación/autorización JWT con filtros stateless; todos los endpoints están protegidos salvo login y registro. SecurityConfig, JwtTokenProvider, JwtAuthenticationFilter, AuthController
- Modelo de dominio que cubre usuarios, roles, plantillas de actividades, sets, asignaciones e historial de puntajes, expuesto mediante DTOs MapStruct. User, Role, ActivityTemplate, ActivitySet, Assignment, ScoreHistory, UserMapper
- Respuesta consistente mediante
ApiResponsey manejo centralizado de errores con códigos HTTP claros. ApiResponse, GlobalExceptionHandler
- Visión general
- Arquitectura de solución
- Seguridad
- Configuración y perfiles
- REST API
- Errores y contratos
- Puesta en marcha
- Pruebas
- Documentación automática
- Autor
El servicio orquesta plantillas de actividades semanales, las asigna a colaboradores, registra entregas y ajusta puntajes de desempeño. Usa starters de Spring Boot para web, seguridad, validación y JPA; JJWT para tokens; SpringDoc para OpenAPI; Flyway para migraciones; y Lombok/MapStruct para reducir boilerplate. F: pom.xml L40–L124 · F: GradingApplication.java L14–L24
- Controladores REST coordinan HTTP para autenticación, usuarios, roles, sets, plantillas, asignaciones e historial de puntajes. AuthController, UserController, RoleController, ActivitySetController, ActivityTemplateController, AssignmentController, ScoreHistoryController
- Servicios contienen reglas de negocio para CRUD, validaciones, ajustes de puntaje, vinculación de plantillas con sets y el flujo de asignaciones. AuthServiceImpl, UserServiceImpl, RoleServiceImpl, ActivitySetServiceImpl, ActivityTemplateServiceImpl, AssignmentServiceImpl, ScoreHistoryServiceImpl
- Mappers y DTOs: MapStruct convierte entidades a DTOs livianos, detallados y de resumen, permitiendo exposición controlada y actualizaciones parciales. UserMapper, RoleMapper, SetMapper, ScoreMapper, TempAssignMapper
- Persistencia: las entidades heredan campos de auditoría desde
BaseEntityy usan relaciones ricas (uno-a-muchos, muchos-a-muchos). BaseEntity, User, ActivityTemplate, ActivitySet, Assignment, ScoreHistory
| Entidad | Propósito |
|---|---|
User |
Colaboradores con credenciales, puntaje actual, roles asignados, asignaciones y registros de puntajes. User |
Role |
Grupo semántico de permisos; se bloquea su eliminación si hay usuarios dependientes. Role, RoleServiceImpl |
ActivityTemplate |
Plantilla reusable (nombre, día de la semana, peso, descripción, flag de activo). F: ActivityTemplate.java L30–L74 |
ActivitySet |
Colección ordenada de plantillas para agrupaciones temáticas. F: ActivitySet.java L30–L61 |
Assignment |
Instancia programada por usuario con estado de entrega, estado de calificación y URL de evidencia opcional. F: Assignment.java L29–L67 |
ScoreHistory |
Ajustes semanales de puntaje con delta y justificación. F: ScoreHistory.java L28–L67 |
- Los controladores comparten el contrato
DtoCrudControllerpara exponer rutas/verbo CRUD uniformes. F: DtoCrudController.java L22–L37 ApiResponseenvuelve cada payload consuccess,message,dataytimestamp. F: ApiResponse.java L6–L56ServiceUtilsayuda a aplicar parches opcionales y a traducirOptionalenEntityNotFoundException. F: ServiceUtils.java L11–L24
- El ciclo de vida de usuarios exige emails únicos, hashea contraseñas con BCrypt, actualiza puntajes y maneja flags de habilitado/bloqueo y asignación de roles. F: UserServiceImpl.java L70–L195
- Los ajustes de puntaje calculan automáticamente deltas, resuelven el inicio de semana y persisten historial. F: UserServiceImpl.java L124–L258
- El servicio de historial evita semanas duplicadas por usuario y expone las diez entradas más recientes. F: ScoreHistoryServiceImpl.java L47–L105
- Las plantillas pueden vincularse a sets con orden incremental y generar asignaciones iniciales para un usuario objetivo. F: ActivityTemplateServiceImpl.java L86–L161
- Las asignaciones soportan filtros por usuario/rango, actualizaciones parciales y sincronización con la plantilla para datos consistentes. F: AssignmentServiceImpl.java L41–L126
La aplicación aplica seguridad JWT sin estado:
SecurityFilterChaindeshabilita CSRF, fija sesiones como stateless, lista blanca/api/auth/**y/actuator/**, y protege el resto de endpoints. F: SecurityConfig.java L49–L63- Contraseñas hasheadas con
BCryptPasswordEncoderde fuerza 12; autenticación delegada a un proveedor DAO usandoUserDetailsServicepersonalizado. F: SecurityConfig.java L28–L41 · F: UserServiceImpl.java L197–L213 - JWTs firmados con HS256, incluyen
issuery expiración configurables, y el filtro extrae tokens Bearer por request para poblar el contexto de seguridad. F: JwtTokenProvider.java L31–L77 · F: JwtAuthenticationFilter.java L25–L60 · F: JwtProperties.java L9–L13 - Login/registro devuelven
AuthResponsecon token, tipo y expiración; credenciales validadas víaAuthenticationManager. F: AuthController.java L28–L37 · F: AuthServiceImpl.java L25–L50 RestAuthenticationEntryPointgarantiza un401JSON para accesos no autorizados, complementando la estrategia de excepciones global. F: RestAuthenticationEntryPoint.java L19–L33 · F: GlobalExceptionHandler.java L24–L64
- Variables externas (
MYSQL_HOST,MYSQL_PORT,MYSQL_DATABASE,MYSQL_USER,MYSQL_PASSWORD,JWT_SECRET,JWT_EXPIRATION_MINUTES) alimentan la configuración de DB y JWT. F: application.properties L16–L24 - Flyway habilitado, formateo SQL activo, y solo
health/infode Actuator expuestos. F: application.properties L6–L14 · F: application.properties L27–L28 - Perfil
devincrementa logs de Hibernate/web;prodajusta niveles y el tamaño del pool HikariCP. F: application-dev.properties L3–L5 · F: application-prod.properties L3–L9 CorsFilterpermitehttp://localhost:8080, cualquier método/cabecera y credenciales para integrar un frontend. F: CorsConfig.java L12–L24@OpenAPIDefinition+@EnableConfigurationPropertiesconectan metadatos Swagger y propiedades de JWT en el arranque. F: GradingApplication.java L14–L24
| Método | Ruta | Descripción |
|---|---|---|
| POST | /api/auth/login |
Autentica credenciales y emite un JWT Bearer. F: AuthController.java L28–L37 |
| POST | /api/auth/register |
Registra un usuario nuevo y devuelve el DTO básico. F: AuthController.java L34–L37 |
| GET | /api/users |
Lista usuarios con sus atributos principales. F: UserController.java L38–L41 |
| GET | /api/users/{id} |
Obtiene un usuario por id. F: UserController.java L43–L46 |
| POST | /api/users |
Crea usuario con password encriptado y roles. F: UserController.java L48–L51 |
| PUT | /api/users |
Actualiza perfil, roles y, si aplica, el puntaje. F: UserController.java L53–L56 |
| DELETE | /api/users/{id} |
Elimina un usuario existente. F: UserController.java L58–L61 |
| GET | /api/users/{id}/detail |
Detalle expandido (roles, asignaciones, puntajes). F: UserController.java L64–L67 |
| GET | /api/users/by-role/{role} |
Filtra usuarios por nombre de rol. F: UserController.java L69–L72 |
| GET | /api/users/search?q= |
Busca por nombre/email. F: UserController.java L74–L77 |
| PATCH | /api/users/{id}/password |
Cambia password validando la actual. F: UserController.java L79–L84 |
| POST | /api/users/{id}/score-adjustments |
Ajusta puntaje y crea entrada de historial. F: UserController.java L86–L90 |
| POST | /api/users/{id}/lock / /unlock |
Bloquea o desbloquea cuentas. F: UserController.java L92–L101 |
| GET | /api/roles |
Lista roles con sus detalles. F: RoleController.java L33–L36 |
| GET | /api/roles/{id} |
Obtiene un rol por id. F: RoleController.java L38–L41 |
| POST | /api/roles |
Crea un rol nuevo verificando duplicados. F: RoleController.java L43–L46 |
| PUT | /api/roles |
Actualiza metadatos del rol. F: RoleController.java L48–L51 |
| DELETE | /api/roles/{id} |
Elimina roles no asignados a usuarios. F: RoleController.java L53–L56 |
| GET | /api/roles/summaries |
Resúmenes ligeros de roles. F: RoleController.java L59–L61 |
| GET | /api/roles/by-name/{name} |
Busca un rol por nombre (case-insensitive). F: RoleController.java L64–L67 |
| GET | /api/activity-sets |
Lista todos los sets. F: ActivitySetController.java L34–L37 |
| GET | /api/activity-sets/{id} |
Obtiene un set por id. F: ActivitySetController.java L39–L42 |
| POST | /api/activity-sets |
Crea un nuevo set. F: ActivitySetController.java L44–L47 |
| PUT | /api/activity-sets |
Actualiza metadatos del set. F: ActivitySetController.java L49–L52 |
| DELETE | /api/activity-sets/{id} |
Elimina un set y sus relaciones. F: ActivitySetController.java L54–L57 |
| GET | /api/activity-sets/{id}/detail |
Vista ordenada con plantillas vinculadas. F: ActivitySetController.java L60–L63 |
| GET | /api/activity-sets/summaries |
Resúmenes con conteo de asignaciones. F: ActivitySetController.java L65–L68 |
| GET | /api/templates |
Lista todas las plantillas. F: ActivityTemplateController.java L36–L39 |
| GET | /api/templates/active |
Solo plantillas activas. F: ActivityTemplateController.java L41–L44 |
| GET | /api/templates/active/by-weekday |
Plantillas activas por día (1–7). F: ActivityTemplateController.java L46–L48 |
| GET | /api/templates/{id} |
Resumen de plantilla. F: ActivityTemplateController.java L51–L54 |
| GET | /api/templates/{id}/detail |
Última asignación o detalle de plantilla. F: ActivityTemplateController.java L56–L59 |
| POST | /api/templates |
Crea plantilla y asignación inicial. F: ActivityTemplateController.java L61–L64 |
| PUT | /api/templates |
Actualiza plantilla y opcionalmente su asignación. F: ActivityTemplateController.java L66–L68 |
| DELETE | /api/templates/{id} |
Elimina plantilla y la desacopla de sets. F: ActivityTemplateController.java L71–L74 |
| GET | /api/assignments |
Lista asignaciones (DTO compacto). F: AssignmentController.java L38–L41 |
| GET | /api/assignments/users/{userId} |
Asignaciones por usuario, descendente. F: AssignmentController.java L43–L46 |
| GET | /api/assignments/range?start=&end= |
Filtra asignaciones por rango de fechas ISO. F: AssignmentController.java L48–L53 |
| GET | /api/assignments/{id} |
Vista detallada de la asignación. F: AssignmentController.java L55–L58 |
| POST | /api/assignments |
Crea una asignación (delegado a creación de plantilla). F: AssignmentController.java L60–L63 |
| PUT | /api/assignments |
Actualiza estado, evidencia o campos de la plantilla vinculada. F: AssignmentController.java L65–L68 |
| DELETE | /api/assignments/{id} |
Elimina asignación manteniendo integridad de la plantilla. F: AssignmentController.java L70–L73 |
| GET | /api/score-history |
Lista el historial completo de puntajes. F: ScoreHistoryController.java L34–L37 |
| GET | /api/score-history/{id} |
Obtiene una entrada específica. F: ScoreHistoryController.java L39–L42 |
| POST | /api/score-history |
Crea registro imponiendo semana única por usuario. F: ScoreHistoryController.java L44–L47 · F: ScoreHistoryServiceImpl.java L47–L57 |
| PUT | /api/score-history |
Actualiza campos permitidos. F: ScoreHistoryController.java L49–L52 |
| DELETE | /api/score-history/{id} |
Elimina una entrada de historial. F: ScoreHistoryController.java L54–L57 |
| GET | /api/score-history/{id}/detail |
Detalle incluyendo usuario vinculado. F: ScoreHistoryController.java L60–L63 |
| GET | /api/score-history/users/{userId}/recent |
Diez entradas más recientes por usuario. F: ScoreHistoryController.java L65–L68 · F: ScoreHistoryServiceImpl.java L85–L90 |
Las respuestas siempre usan el sobre ApiResponse. Las excepciones de dominio (usuarios/roles inexistentes, credenciales inválidas, conflictos) son interceptadas por GlobalExceptionHandler, devolviendo códigos precisos (404, 401, 400, 409, 500) y timestamps. F: ApiResponse.java L6–L56 · F: GlobalExceptionHandler.java L14–L65
-
Prerrequisitos
- JDK 21 y Maven Wrapper (
mvnw) incluidos en el repo. F: pom.xml L29–L35 · F: mvnw (cabecera) - Base MySQL accesible usando el patrón de URL en
spring.datasource.url; Flyway aplicará migraciones cuando existan. F: application.properties L6–L19
- JDK 21 y Maven Wrapper (
-
Configura variables de entorno
- Provee credenciales de DB y secretos JWT (
MYSQL_HOST,MYSQL_DATABASE,MYSQL_USER,MYSQL_PASSWORD,JWT_SECRET,JWT_EXPIRATION_MINUTES). F: application.properties L16–L24
- Provee credenciales de DB y secretos JWT (
-
Ejecuta la aplicación
./mvnw spring-boot:run
Elige el perfil con
-Dspring.profiles.active=devoprodsegún necesidad. F: application-dev.properties L3–L5 · F: application-prod.properties L3–L9 -
Empaqueta el jar ejecutable (opcional)
./mvnw clean package
Ejecuta tests de unidad/integración con:
./mvnw testUn @SpringBootTest verifica que el contexto de Spring cargue correctamente. F: GradingApplicationTests.java L6–L11
@OpenAPIDefinition y el starter de SpringDoc exponen Swagger UI (/swagger-ui.html) y los specs OpenAPI (/v3/api-docs) en ejecución. F: pom.xml L79–L84 · F: GradingApplication.java L14–L24
🛠️ Desarrollado con 💙 por Studios TKOH