Skip to content

BryanStrk/drive-arena-backend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

100 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🏁 Drive Arena — Backend

Plataforma experiencial de motorsport en resort · API REST y motor de negocio

Java Spring Boot MySQL Maven JWT License Version


📋 Tabla de contenidos


🎯 Visión general

Drive Arena Backend es la API REST y el motor de reglas de negocio del resort experiencial Drive Arena. Gestiona el ciclo completo de una sesión: desde la venta de pases en taquilla y la asignación de turnos, hasta el registro de tiempos en circuito, la emisión automática de recompensas y el control operativo de mantenimientos.

Construida sobre **Spring Boot 4 con arquitectura package-by-feature**, expone endpoints autenticados mediante JWT, persiste sobre MySQL 8 y delega el almacenamiento de imágenes a Cloudinary.

🛠 Stack tecnológico

Capa Tecnología Versión
Lenguaje Java 25
Framework Spring Boot 4.0.x
Seguridad Spring Security + JWT (jjwt) 0.12.6
Persistencia Spring Data JPA + Hibernate 7.x
Base de datos MySQL 8.0
Documentación springdoc-openapi (Swagger UI) 2.x
Build Maven Wrapper 3.9+
Cloud Storage Cloudinary SDK
Email Spring Boot Starter Mail
Productividad Lombok
Observabilidad Spring Boot Actuator

🏗 Arquitectura

Organización: Package-by-Feature

A partir de la versión v1.4.0 el proyecto migró desde una estructura por capas (controllers/, services/, repositories/) hacia una organización por feature donde cada dominio del negocio agrupa todas sus piezas:

com.driveArena.backend/
├── atraccion/          # CRUD + lógica de atracciones del parque
├── cliente/            # Gestión de clientes y búsqueda paginada
├── circuito/           # Circuitos y registro de tiempos
├── compra/             # Ventas, taquilla y entradas
├── dashboard/          # Métricas agregadas y KPIs
├── empleado/           # Empleados y turnos
├── hotel/              # Lodges/hoteles del resort
├── mantenimiento/      # Operativa técnica multi-técnico
├── pase/               # PaseGratuito (gamificación)
├── shared/             # Excepciones, GlobalExceptionHandler, utilidades
├── tarifa/             # Tarifas y políticas de precio
├── turno/              # Turnos de empleados
└── usuarioSistema/     # Usuarios con rol (ADMIN/TAQUILLA/TÉCNICO)

Cada feature internamente sigue el patrón Controller → Service → Repository con DTOs específicos (Request / Response), un Mapper manual basado en @Component, y una entidad JPA enriquecida con Lombok.

Capas internas

HTTP Request
    │
    ▼
┌─────────────┐
│ Controller  │  ← @RestController · valida @Valid · gobierna HTTP semantics
└─────┬───────┘
      │
      ▼
┌─────────────┐
│   Service   │  ← @Service · lógica de negocio · @Transactional · orquesta agregados
└─────┬───────┘
      │
      ▼
┌─────────────┐
│ Repository  │  ← @Repository extends JpaRepository · queries derivadas y @Query
└─────┬───────┘
      │
      ▼
   MySQL 8

Excepciones de negocio (ConflictException, ForbiddenOperationException, MailDeliveryException, etc.) se capturan en un GlobalExceptionHandler centralizado que devuelve ProblemDetail (RFC 7807) consistente al cliente.


⚡ Features

Gestión operativa

  • CRUDs completos sobre Atracción, Tarifa, Cliente, Empleado, Compra+Entrada, Turno, Mantenimiento y UsuarioSistema.
  • Paginación server-side con filtros y búsqueda en clientes, ventas y usuarios (Pageable + Spring Data).
  • Mantenimiento multi-técnico vía tabla intermedia mantenimiento_tecnicos, con asignación dinámica y endpoints PATCH para cambio de estado.
  • Dashboard con métricas agregadas: ingresos mensuales, top lodges, ventas por rango de edad, mantenimientos pendientes.

Gamificación (NIVEL B)

  • PaseGratuito autoemitido al detectar podio o récord en un circuito.
  • TiempoCircuito con modelo híbrido (FK Cliente opcional + nombrePiloto siempre obligatorio) para registrar tiempos tanto de clientes registrados como de visitantes ocasionales.
  • CROSS_PROMO hardcodeado en config, mapeando circuito de origen a recompensa cruzada.
  • caducidad calculada dinámicamente desde la última Compra activa, con fallback a 24 h.
  • Autoemisión envuelta en try/catch: el fallo en emitir un pase nunca interrumpe el registro de tiempo.

Email transaccional

  • EmailService con plantillas (reserva-confirmada, ticket-compra) enviadas tras eventos clave.
  • MailDeliveryException propaga errores SMTP sin romper la operación principal.

Cross-cutting

  • Autenticación JWT con BCrypt (10 rounds) para passwords.
  • Cloudinary para almacenamiento de imágenes (perfiles, atracciones, lodges).
  • Swagger UI auto-generado con OpenAPI 3.1.
  • CORS configurado en SecurityFilterChain (no en WebMvcConfigurer) tal como exige Spring Boot 4.
  • Soft-delete protection: un usuario ADMIN no puede borrarse a sí mismo.

🚀 Quick Start

Prerequisitos

  • Java 25 (JDK)
  • MySQL 8.0 corriendo en local o accesible vía red
  • Maven Wrapper incluido en el repo (no requiere Maven instalado)

Pasos

# 1. Clonar
git clone https://github.com/BryanStrk/drive-arena-backend.git
cd drive-arena-backend

# 2. Crear base de datos
mysql -u root -p -e "CREATE DATABASE drive_arena CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# 3. Configurar variables (ver siguiente sección)
cp .env.example .env
# edita .env con tus credenciales

# 4. Compilar
./mvnw clean compile

# 5. Arrancar
./mvnw spring-boot:run

La API quedará disponible en http://localhost:8080.

Swagger UI: http://localhost:8080/swagger-ui.html


🔐 Variables de entorno

Las credenciales nunca deben estar hardcodeadas ni en git. El proyecto usa el patrón de IntelliJ Run Configurations con variables separadas por ;:

# Base de datos
DB_URL=jdbc:mysql://localhost:3306/drive_arena
DB_USERNAME=tu_usuario
DB_PASSWORD=tu_password

# JWT
JWT_SECRET=clave_secreta_minimo_256_bits_codificada_en_base64
JWT_EXPIRATION_MS=86400000

# Cloudinary
CLOUDINARY_CLOUD_NAME=tu_cloud
CLOUDINARY_API_KEY=tu_key
CLOUDINARY_API_SECRET=tu_secret

# Email SMTP
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=tu_email@gmail.com
MAIL_PASSWORD=tu_app_password

# CORS
CORS_ALLOWED_ORIGINS=http://localhost:5173,https://drive-arena.vercel.app

application.properties está incluido en .gitignore. El template público es application.properties.example.


📚 Documentación API

Tras arrancar el backend, la documentación interactiva está disponible en:

  • Swagger UI: http://localhost:8080/swagger-ui.html
  • OpenAPI JSON: http://localhost:8080/v3/api-docs

Endpoints principales (resumen)

Recurso Base path Roles
Autenticación /api/auth público
Usuarios sistema /api/usuarios ADMIN
Clientes /api/clientes ADMIN, TAQUILLA
Compras (ventas) /api/compras ADMIN, TAQUILLA
Atracciones /api/atracciones ADMIN
Lodges /api/hoteles ADMIN
Circuitos /api/circuitos ADMIN, TÉCNICO
Tiempos de circuito /api/tiempos-circuito ADMIN, TÉCNICO
Pases gratuitos /api/pases ADMIN
Mantenimientos /api/mantenimientos ADMIN, TÉCNICO
Dashboard /api/dashboard ADMIN

Nota: la autorización por rol se aplica vía @PreAuthorize("hasRole('XXX')") a nivel de método.


📁 Estructura del proyecto

drive-arena-backend/
├── src/
│   ├── main/
│   │   ├── java/com/driveArena/backend/
│   │   │   ├── atraccion/
│   │   │   ├── auth/                  ← JWT, login, AuthController
│   │   │   ├── cliente/
│   │   │   ├── circuito/
│   │   │   ├── compra/
│   │   │   ├── config/                ← SecurityConfig, CorsConfig, OpenApiConfig
│   │   │   ├── dashboard/
│   │   │   ├── empleado/
│   │   │   ├── hotel/
│   │   │   ├── mantenimiento/
│   │   │   ├── pase/
│   │   │   ├── shared/                ← exceptions, GlobalExceptionHandler, utils
│   │   │   ├── tarifa/
│   │   │   ├── turno/
│   │   │   ├── usuarioSistema/
│   │   │   └── DriveArenaBackendApplication.java
│   │   └── resources/
│   │       ├── templates/             ← plantillas email (Thymeleaf)
│   │       │   ├── reserva-confirmada.html
│   │       │   └── ticket-compra.html
│   │       ├── application.properties (gitignored)
│   │       └── application.properties.example
│   └── test/
│       └── java/com/driveArena/backend/   ← estructura preparada, tests pendientes
├── AUDIT.md                           ← auditoría arquitectónica del refactor v1.4.0
├── pom.xml
├── mvnw / mvnw.cmd
└── README.md

🗄 Modelo de datos

Tablas principales

usuario_sistema  ──┐
                   │ (auditoría)
                   ▼
cliente ─── compra ─── entrada ─── atraccion
            │                       │
            │                       └─── tarifa
            │
            └──── hotel (opcional, lodges)
                     │
                     └── zona, esVip

circuito ─── tiempo_circuito ─── cliente (opcional)
                    │
                    └─── pase_gratuito (autoemitido)

mantenimiento ─── mantenimiento_tecnicos ─── usuario_sistema (rol TÉCNICO)
       │
       └── atraccion / circuito (afectado)

empleado ─── turno

Migraciones

El proyecto usa ddl-auto=validate en producción. Cambios de schema se aplican mediante migraciones SQL manuales versionadas documentadas en commits independientes (chore(db): ALTER TABLE ...).


🔒 Seguridad y autorización

Autenticación

  • Endpoint /api/auth/login recibe username + password, valida contra BCryptPasswordEncoder, y devuelve un JWT firmado con HS256.
  • El JWT se incluye en cada petición autenticada vía header Authorization: Bearer <token>.
  • JwtAuthenticationFilter (extends OncePerRequestFilter) intercepta cada request, valida el token y popula el SecurityContext.

Autorización

  • Roles soportados: ADMIN, TAQUILLA, TÉCNICO.
  • Cada endpoint protegido usa @PreAuthorize("hasRole('XXX')") o hasAnyRole(...).
  • Operaciones sensibles (eliminar usuario, cambiar rol) incluyen soft-delete protection y validación contra el principal actual.

CORS

Configurado dentro del SecurityFilterChain (no como WebMvcConfigurer, ya que Spring Boot 4 lo requiere así):

http.cors(cors -> cors.configurationSource(corsConfigurationSource()));

🚢 Despliegue

Producción actual

  • VPS: IONOS Ubuntu 24.04 — 2 vCPU / 2 GB RAM.
  • Frente: Nginx como reverse proxy + TLS (Let's Encrypt).
  • Proceso: unidad systemd con auto-restart.
  • Build: ./mvnw clean package -DskipTests → JAR ejecutable.

Configuración Nginx (extracto)

location /api/ {
    proxy_pass http://localhost:8080/;   # trailing slash importante: strip del prefijo
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Unit systemd (extracto)

[Service]
EnvironmentFile=/etc/drive-arena/env
ExecStart=/usr/bin/java -jar /opt/drive-arena/backend.jar
Restart=always
RestartSec=5

🧪 Testing

El proyecto incluye las dependencias de test ya configuradas en pom.xml:

  • spring-boot-starter-test (JUnit 5, Mockito, AssertJ)
  • spring-security-test
  • testcontainers-mysql (para tests de integración)
  • rest-assured

La estructura de carpetas está preparada en src/test/java/, pero la cobertura de tests automatizados es parte de la siguiente iteración tras la entrega del TFG. La validación actual se ha hecho mediante Postman y QA manual end-to-end.


🏷 Versionado

Tag Hito
v1.0.0 Primera entrega funcional con CRUDs base
v1.2.0 Sistema de autenticación JWT + Spring Security
v1.3.0 NIVEL B de gamificación (PaseGratuito + TiempoCircuito + CROSS_PROMO)
v1.4.0 Refactor arquitectónico: package-by-feature
v2.0.0 Port de roles (TÉCNICO), multi-técnico en mantenimientos, dashboard, paginación

📝 Convenciones de Git

El proyecto sigue Conventional Commits y GitFlow simplificado:

Tipo Uso
feat Nueva funcionalidad
fix Corrección de bug
refactor Cambio sin alterar comportamiento externo
chore Mantenimiento, dependencias, config
docs Solo documentación
test Solo tests

Workflow

git checkout -b feature/nombre-acotado
# trabajo + commits atómicos
git checkout main
git merge feature/nombre-acotado --no-ff   # historia explícita
git tag -a vX.Y.Z -m "..."
git push origin main --tags

👤 Autor

Bryan Alejandro Paico AlbinesDesarrollo de Aplicaciones Web (DAW) · 2026


📄 Licencia

Proyecto académico desarrollado como Trabajo academico de Desarrollo de Aplicaciones Web. Uso no comercial.

Drive Arena · Conduce · Compite · Domina

About

Drive Arena - Resort Experiencial Motorsport - Backend API (Spring Boot 4 + Java 25 + MySQL)

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors