La tienda ya vende con transacciones; le falta saber quién compra y quién administra. Este hito aplica el tema 06 — Login con JWT: el módulo users con registro y login, el par de tokens — access JWT de vida corta y refresh opaco persistido — y la validación stateless en un filtro propio. La autorización declarativa llega en el hito siguiente.
| Pieza | Cambio en este hito |
|---|---|
| Contrato | v1.0.0: registro y login; el pedido toma la identidad del token |
| Estructura | Módulo users nuevo, que nace ya con JPA |
| Mecanismo | Access JWT + refresh opaco con rotación; filtro Servlet propio |
openapi.yaml a v1.0.0 — cambio breaking, por eso salta de versión mayor:| Operación | Petición | Respuestas |
|---|---|---|
| Registro | POST /api/users · UserRequest | 201 · 400 · 409 |
| Login | POST /api/auth/login · LoginRequest | 200 · 401 |
| Refresh | POST /api/auth/refresh · RefreshToken | 200 · 401 |
| Logout | POST /api/auth/logout · RefreshToken | 204 · 401 |
| Mis pedidos | GET /api/me/orders | 200 · 401 |
name, email y password (mínimo 8). Login y refresh devuelven TokenResponse: accessToken, refreshToken y expiresIn. El logout revoca el refresh que recibe.OrderRequest pierde userId — la identidad del comprador ya no viaja en el cuerpo, sino en el token. Los pedidos de prueba de los hitos anteriores se limpian: su userId era provisional.domain y mecanismo JPA en persistence.users y refresh_tokens de la especificación: ampliar el init.sql y reiniciar el volumen de MariaDB. La semilla trae un usuario ADMIN con su hash; el registro crea siempre USER.refresh_tokens de la especificación existe por eso.
GET /api/me/orders devuelve solo los pedidos del comprador: la identidad viene del token, no de un parámetro.OrderRequest ya no lleva userId.hito-08.Siguiente hito: hito 09 — Integración con Spring Security.