API Contract: Users & Auth¶
Proposito¶
Contrato completo de los endpoints de autenticacion y gestion de usuarios del Sistema de Turnos Medicos.
Metadata¶
| Campo | Valor |
|---|---|
| Recurso | Users / Auth |
| Base URL | /api/v1/auth, /api/v1/users |
| Autor | Maria Lopez |
| Fecha | 2025-03-20 |
| Estado | Agreed |
| Spec relacionada | feature-user-auth.spec.md |
Convenciones Generales¶
Autenticacion¶
Bearer token JWT en header Authorization. Los endpoints de registro y login son publicos.
Content Type¶
application/json
Formato de Errores¶
Endpoints¶
POST /api/v1/auth/register¶
Descripcion: Registra un nuevo paciente en el sistema.
Autorizacion: Publico (sin token).
Request:
Body:
{
"email": "juan.perez@email.com",
"password": "MiPassword123",
"firstName": "Juan",
"lastName": "Perez"
}
| Campo | Tipo | Requerido | Validacion |
|---|---|---|---|
| string | Si | Email valido, max 255 chars | |
| password | string | Si | Min 8 chars, 1 mayuscula, 1 numero |
| firstName | string | Si | Min 2, max 100 chars |
| lastName | string | Si | Min 2, max 100 chars |
Response exitosa:
Status: 201 Created
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "juan.perez@email.com",
"firstName": "Juan",
"lastName": "Perez",
"role": "PATIENT",
"isVerified": false,
"createdAt": "2025-03-20T10:30:00Z"
},
"message": "Cuenta creada. Revisa tu email para verificar."
}
Responses de error:
| Status | Code | Cuando |
|---|---|---|
| 400 | VALIDATION_ERROR | Campos faltantes o formato invalido |
| 409 | EMAIL_ALREADY_EXISTS | El email ya esta registrado |
| 429 | RATE_LIMIT_EXCEEDED | Mas de 10 registros por IP en 1 minuto |
POST /api/v1/auth/verify-email¶
Descripcion: Verifica el email de un usuario con el token enviado por email.
Autorizacion: Publico.
Request:
Body:
Response exitosa:
Status: 200 OK
Responses de error:
| Status | Code | Cuando |
|---|---|---|
| 400 | INVALID_TOKEN | Token invalido o malformado |
| 410 | TOKEN_EXPIRED | Token expiro (24h) |
POST /api/v1/auth/login¶
Descripcion: Autentica un usuario y retorna tokens.
Autorizacion: Publico.
Request:
Body:
Response exitosa:
Status: 200 OK
{
"data": {
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
"expiresIn": 900,
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "juan.perez@email.com",
"firstName": "Juan",
"lastName": "Perez",
"role": "PATIENT"
}
}
}
Responses de error:
| Status | Code | Cuando |
|---|---|---|
| 401 | INVALID_CREDENTIALS | Email o password incorrecto |
| 403 | EMAIL_NOT_VERIFIED | La cuenta no ha verificado el email |
| 423 | ACCOUNT_LOCKED | Cuenta bloqueada por intentos fallidos |
| 429 | RATE_LIMIT_EXCEEDED | Mas de 10 intentos por IP en 1 minuto |
POST /api/v1/auth/refresh¶
Descripcion: Renueva el access token usando un refresh token valido.
Autorizacion: Publico (el refresh token actua como credencial).
Request:
Body:
Response exitosa:
Status: 200 OK
Responses de error:
| Status | Code | Cuando |
|---|---|---|
| 401 | INVALID_REFRESH_TOKEN | Token invalido, expirado, o revocado |
POST /api/v1/auth/forgot-password¶
Descripcion: Envia un email de reset de password.
Autorizacion: Publico.
Request:
Body:
Response exitosa:
Status: 200 OK
Nota: Siempre retorna 200 para no revelar si el email existe.
POST /api/v1/auth/reset-password¶
Descripcion: Cambia el password usando el token de reset.
Autorizacion: Publico.
Request:
Body:
Response exitosa:
Status: 200 OK
Responses de error:
| Status | Code | Cuando |
|---|---|---|
| 400 | INVALID_TOKEN | Token invalido |
| 400 | PASSWORD_RECENTLY_USED | El password es igual a uno de los ultimos 3 |
| 410 | TOKEN_EXPIRED | Token expiro |
GET /api/v1/users/me¶
Descripcion: Retorna el perfil del usuario autenticado.
Autorizacion: Cualquier usuario autenticado.
Request:
Headers:
Response exitosa:
Status: 200 OK
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "juan.perez@email.com",
"firstName": "Juan",
"lastName": "Perez",
"role": "PATIENT",
"isVerified": true,
"createdAt": "2025-03-20T10:30:00Z"
}
}
PATCH /api/v1/users/me¶
Descripcion: Actualiza el perfil del usuario autenticado.
Autorizacion: Cualquier usuario autenticado.
Request:
Body:
Campos editables: firstName, lastName (el email no se puede cambiar en v1).
Response exitosa:
Status: 200 OK
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "juan.perez@email.com",
"firstName": "Juan Carlos",
"lastName": "Perez Garcia",
"role": "PATIENT",
"isVerified": true,
"createdAt": "2025-03-20T10:30:00Z"
}
}
Codigos de Error Especificos¶
| Code | HTTP Status | Descripcion |
|---|---|---|
| EMAIL_ALREADY_EXISTS | 409 | El email ya esta registrado |
| INVALID_CREDENTIALS | 401 | Email o password incorrecto |
| EMAIL_NOT_VERIFIED | 403 | Cuenta sin verificacion de email |
| ACCOUNT_LOCKED | 423 | Cuenta bloqueada por intentos fallidos |
| INVALID_TOKEN | 400 | Token invalido o malformado |
| TOKEN_EXPIRED | 410 | Token expiro |
| INVALID_REFRESH_TOKEN | 401 | Refresh token invalido, expirado, o revocado |
| PASSWORD_RECENTLY_USED | 400 | Password igual a uno de los ultimos 3 |
| RATE_LIMIT_EXCEEDED | 429 | Demasiados requests |
Checklist de Completitud¶
- Todos los endpoints documentados
- Request y response con ejemplos concretos
- Errores documentados con codigos especificos
- Autorizacion especificada por endpoint
- Revisada por frontend team
- Revisada por otro ingeniero backend
- Derivados generados (test plan / OpenAPI spec)
Archivos relacionados¶
- _template.api.md - Plantilla de API
- api-bookings.md - API de reservas
- ../01-specs/feature-user-auth.spec.md - Spec de autenticacion
- ../05-testing-strategy/test-plan-auth.md - Plan de pruebas