REST API para gestión de tareas con autenticación JWT, persistencia poliglota (PostgreSQL + MongoDB), y operaciones CRUD con filtering y pagination.
- Java 21
- Spring Boot 4.0 — Spring Security 6, Spring Data JPA, Spring Data MongoDB
- PostgreSQL — datos transaccionales (tareas, usuarios)
- MongoDB — log de actividad inmutable
- JWT (HS256) — autenticación con refresh tokens de rotación single-use
- Bucket4j — rate limiting
- Docker Compose — infraestructura local
- GitHub Actions — CI/CD con Testcontainers
- JUnit 5 + Mockito — 51 unit tests + 6 integration tests
- JaCoCo — quality gates (LINE 0.85 / BRANCH 0.80)
- Terraform — IaC para AWS (EC2 + RDS)
┌────────────────────┐
│ Cliente REST │
└────────┬───────────┘
│ JWT Bearer Token
v
┌────────────────────────────────────────┐
│ API REST (Spring Boot) │
│ ├─ Spring Security (JWT validation) │
│ ├─ DTO projections (JPA) │
│ ├─ Auditoría automática │
│ └─ Soft delete + Optimistic locking │
└────────┬───────────────────────────────┘
│
┌──┴──────────────────────────┐
│ │
v v
┌──────────────────┐ ┌──────────────────┐
│ PostgreSQL │ │ MongoDB │
│ (transaccional) │ │ (audit logs) │
│ • users │ │ • activity │
│ • tasks │ │ • immutable │
│ • audit_trail │ └──────────────────┘
└──────────────────┘
- Java 21+
- Maven 3.9+
- Docker y Docker Compose
- Git
-
Clona el repositorio:
git clone https://github.com/Toleflaco/task-manager-api.git cd task-manager-api -
Copia el archivo de configuración de ejemplo:
cp .env.example .env
Edita
.envsi necesitas cambiar puertos o credenciales:POSTGRES_USER=taskmanager POSTGRES_PASSWORD=secret POSTGRES_DB=taskmanager_db MONGO_INITDB_ROOT_USERNAME=taskmanager MONGO_INITDB_ROOT_PASSWORD=secret JWT_SECRET=tu-secret-key-muy-largo-y-complejo-aqui -
Levanta PostgreSQL + MongoDB + Redis:
docker compose up -d
-
Arranca la aplicación:
./mvnw spring-boot:run
-
Verifica que está UP:
curl http://localhost:8080/actuator/health
Si prefieres PostgreSQL + MongoDB locales en lugar de contenedores:
-
Crea base de datos PostgreSQL:
psql -U postgres -c "CREATE DATABASE taskmanager_db;" -
Inicia MongoDB local:
mongod
-
Edita
src/main/resources/application.properties:spring.datasource.url=jdbc:postgresql://localhost:5432/taskmanager_db spring.datasource.username=postgres spring.datasource.password=your-password spring.data.mongodb.uri=mongodb://localhost:27017/taskmanager spring.jpa.hibernate.ddl-auto=update
-
Arranca la app:
./mvnw spring-boot:run
Todos los endpoints requieren JWT. Primero regístrate:
# Registro
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"Password123!"}'
# Login
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"Password123!"}'Copia el token de la respuesta y úsalo:
TOKEN="eyJhbGc..."
# Crear tarea
curl -X POST http://localhost:8080/api/tasks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Implementar login","description":"OAuth2 + Keycloak"}'
# Listar tareas (con pagination)
curl "http://localhost:8080/api/tasks?page=0&size=10&sort=createdDate,desc" \
-H "Authorization: Bearer $TOKEN"
# Obtener tarea por ID
curl http://localhost:8080/api/tasks/{taskId} \
-H "Authorization: Bearer $TOKEN"
# Actualizar tarea
curl -X PUT http://localhost:8080/api/tasks/{taskId} \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Implementar logout"}'
# Eliminar tarea (soft delete)
curl -X DELETE http://localhost:8080/api/tasks/{taskId} \
-H "Authorization: Bearer $TOKEN"Ejecuta la suite de tests (unit + integration con Testcontainers):
./mvnw verifyCoverage JaCoCo:
open target/site/jacoco/index.html- JWT (HS256) — tokens sin estado
- Refresh tokens con rotación single-use — detección de reuso por familia de tokens
- Auditoría automática — @CreatedDate, @LastModifiedDate, @CreatedBy en todas las entidades
- Soft delete — tareas nunca se eliminan, solo se marcan como deleted
- PostgreSQL — datos transaccionales (tareas, usuarios, logs auditables)
- MongoDB — log de actividad inmutable, sin joins, optimizado para lectura temporal
- JPA Specifications — queries dinámicas sin Query DSL
- Optimistic locking — previene lost updates en concurrencia
- DTO projections — fetching selectivo de columnas (N+1 prevention)
- Bucket4j — rate limiting configurable por endpoint
- JaCoCo — quality gates enforzadas (LINE 0.85 / BRANCH 0.80)
- GitHub Actions — build, tests, Docker image push
- Testcontainers — integration tests con PostgreSQL + MongoDB reales
- Quality gates — JaCoCo + SonarQube ready
src/main/java/com/taskmanager/
├── task/
│ ├── domain/
│ │ ├── Task.java
│ │ └── TaskRepository.java
│ ├── application/
│ │ ├── TaskService.java
│ │ └── TaskDTO.java
│ └── presentation/
│ └── TaskController.java
├── auth/
│ ├── domain/
│ ├── application/
│ └── presentation/
└── shared/
├── security/
├── error/
└── audit/
Ventaja: cambios en un feature no rozan otros packages.
Cada acción (create, update, delete) genera un documento en activity_log de MongoDB:
{
"_id": ObjectId(...),
"aggregateId": "task-123",
"eventType": "TaskCreated",
"timestamp": ISODate(...),
"userId": "user-456",
"payload": {
"title": "Implementar login",
"description": "OAuth2"
}
}Nunca se modifica ni se borra. Fuente de verdad para auditoría legal y trazabilidad.
Cada refresh genera un nuevo par (access + refresh). El refresh antiguo se invalida:
1. POST /auth/login → {accessToken, refreshToken}
2. POST /auth/refresh → {accessToken: NEW, refreshToken: NEW}
3. Intento reutilizar el refresh antiguo → 401 Unauthorized
(señal de posible token theft)
Detalles en AuthService.java.
Infraestructura IaC en terraform/:
# EC2 para la app (t3.micro, free tier)
resource "aws_instance" "app" {
ami = "ami-0c55b159cbfafe1f0" # Ubuntu 22.04 LTS
instance_type = "t3.micro"
}
# RDS PostgreSQL (db.t3.micro, free tier)
resource "aws_db_instance" "postgres" {
engine = "postgres"
instance_class = "db.t3.micro"
allocated_storage = 20
}Deploy:
cd terraform
terraform init
terraform plan
terraform apply- Cloud Roadmap — AWS, Kubernetes, OAuth2, Observabilidad
- AI Engineer Roadmap — Spring AI, agentes, RAG
Última actualización: 2026-09-20