feat(auth): add user registration and response DTOs, implement registration endpoint in AuthService

feat(auth): create registration route and integrate with AuthService
feat(auth): implement user registration logic in AuthService with Keycloak integration
fix(config): add Keycloak admin credentials to settings
fix(middleware): update tenant middleware to include new auth routes
chore(docs): remove outdated testing guide and add project architecture documentation
feat(frontend): implement user registration page and integrate with API
feat(frontend): create login page with tenant selection and error handling
refactor(frontend): update layout to use custom auth store and improve loading states
This commit is contained in:
2025-10-19 21:05:07 -05:00
parent 58a2f0ade6
commit f460c2b8aa
16 changed files with 559 additions and 1090 deletions

View File

@@ -1,417 +0,0 @@
# Guía de Prueba Rápida - Anexo76
Esta guía te ayudará a probar todas las funcionalidades básicas de Anexo76 después de la instalación.
## Prerrequisitos
✅ Haber ejecutado `./start.sh` exitosamente
✅ Haber configurado Keycloak siguiendo `docs/KEYCLOAK_SETUP.md`
✅ Tener los servicios corriendo
## Verificar Estado de Servicios
```bash
docker-compose ps
```
Deberías ver 4 servicios en estado "Up":
- postgres
- keycloak
- backend
- frontend
## 1. Probar Backend API
### Health Check
```bash
curl http://localhost:8000/health
```
Respuesta esperada:
```json
{
"status": "healthy",
"environment": "development"
}
```
### Status de API
```bash
curl http://localhost:8000/v1/status
```
Respuesta esperada:
```json
{
"status": "ok",
"version": "1.0.0",
"api": "v1"
}
```
### Documentación Interactiva
Abrir en navegador: http://localhost:8000/docs
Deberías ver la interfaz Swagger UI con todos los endpoints documentados.
## 2. Probar Autenticación con Keycloak
### Obtener Token (vía API directa)
```bash
# Reemplaza YOUR_CLIENT_SECRET con el secret de Keycloak
curl -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=anexo76-backend" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "username=demo" \
-d "password=demo123" \
-d "grant_type=password"
```
Respuesta esperada (fragmento):
```json
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer"
}
```
### Usar Token para Llamar API
```bash
# Guarda el access_token en una variable
TOKEN="tu-access-token-aqui"
# Llamar endpoint protegido
curl -X GET http://localhost:8000/v1/auth/me \
-H "Authorization: Bearer $TOKEN"
```
Respuesta esperada:
```json
{
"sub": "a1b2c3d4-...",
"email": "demo@empresa-demo.com",
"name": "Usuario Demo",
"preferred_username": "demo",
"tenant_id": 1,
"roles": ["user", "admin"]
}
```
## 3. Probar Módulo de Tenants
### Listar Tenants (requiere rol admin)
```bash
curl -X GET http://localhost:8000/v1/tenants \
-H "Authorization: Bearer $TOKEN"
```
Respuesta esperada:
```json
{
"tenants": [
{
"id": 1,
"name": "Empresa Demo S.A. de C.V.",
"slug": "empresa-demo",
"type": "shared",
"keycloak_realm": "master",
"is_active": true,
...
}
],
"total": 1,
"page": 1,
"page_size": 50
}
```
### Obtener Tenant por ID
```bash
curl -X GET http://localhost:8000/v1/tenants/1 \
-H "Authorization: Bearer $TOKEN"
```
### Obtener Tenant por Slug
```bash
curl -X GET http://localhost:8000/v1/tenants/slug/empresa-demo \
-H "Authorization: Bearer $TOKEN"
```
## 4. Probar Módulo de Licencias
### Obtener Mi Licencia
```bash
curl -X GET http://localhost:8000/v1/licenses/my-license \
-H "Authorization: Bearer $TOKEN"
```
Respuesta esperada:
```json
{
"id": 1,
"tenant_id": 1,
"plan": "professional",
"status": "active",
"max_users": 50,
"max_storage_gb": 100,
"max_monthly_operations": 25000,
"feature_api_access": true,
"feature_advanced_reports": true,
"feature_integrations": true,
"feature_dedicated_support": false,
"expires_at": "2026-10-17T...",
...
}
```
### Validar Licencia
```bash
curl -X GET http://localhost:8000/v1/licenses/validate/1 \
-H "Authorization: Bearer $TOKEN"
```
Respuesta esperada:
```json
{
"is_valid": true,
"status": "active",
"plan": "professional",
"expires_at": "2026-10-17T...",
"reason": null
}
```
### Obtener Uso de Licencia
```bash
curl -X GET http://localhost:8000/v1/licenses/usage/1 \
-H "Authorization: Bearer $TOKEN"
```
## 5. Probar Frontend
### Abrir Aplicación
Abrir en navegador: http://localhost:5173
### Probar Login
1. Click en botón "Iniciar Sesión"
2. Serás redirigido a Keycloak
3. Ingresar credenciales:
- Usuario: `demo`
- Password: `demo123`
4. Deberías ser redirigido de vuelta al dashboard
### Verificar Dashboard
Después del login, deberías ver:
- ✅ Nombre y email del usuario
- ✅ Información de licencia (plan, estado, límites)
- ✅ Información de usuario (ID, roles, tenant ID)
- ✅ Botón "Cerrar Sesión"
### Probar Logout
1. Click en "Cerrar Sesión"
2. Deberías volver a la pantalla de bienvenida
## 6. Pruebas de Middleware
### Probar sin Token (debe fallar)
```bash
curl -X GET http://localhost:8000/v1/tenants/1
```
Respuesta esperada (error 401):
```json
{
"detail": "Missing or invalid authorization header"
}
```
### Probar con Token Inválido (debe fallar)
```bash
curl -X GET http://localhost:8000/v1/tenants/1 \
-H "Authorization: Bearer token-invalido"
```
Respuesta esperada (error 401):
```json
{
"detail": "Could not validate credentials"
}
```
### Probar sin Tenant ID en Token (debe fallar)
Si el token no tiene `tenant_id`, debería recibir error 400:
```json
{
"detail": "Tenant ID not found in token"
}
```
## 7. Verificar Logs
### Ver logs de todos los servicios
```bash
docker-compose logs -f
```
### Ver logs solo del backend
```bash
docker-compose logs -f backend
```
### Ver logs solo del frontend
```bash
docker-compose logs -f frontend
```
### Ver logs de PostgreSQL
```bash
docker-compose logs -f postgres
```
## 8. Probar Base de Datos
### Conectarse a PostgreSQL
```bash
docker-compose exec postgres psql -U postgres -d anexo76_core
```
### Consultas útiles
```sql
-- Ver tenants
SELECT * FROM tenants;
-- Ver licencias
SELECT * FROM licenses;
-- Ver información de licencia con tenant
SELECT t.name, t.slug, l.plan, l.status, l.expires_at
FROM tenants t
JOIN licenses l ON l.tenant_id = t.id;
-- Salir
\q
```
## 9. Casos de Prueba Adicionales
### Crear Nuevo Tenant (requiere rol admin)
```bash
curl -X POST http://localhost:8000/v1/tenants \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Nueva Empresa S.A.",
"slug": "nueva-empresa",
"keycloak_realm": "master",
"type": "shared",
"contact_name": "Juan Pérez",
"contact_email": "juan@nueva-empresa.com"
}'
```
### Actualizar Tenant
```bash
curl -X PUT http://localhost:8000/v1/tenants/1 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"contact_phone": "+52 55 9999 8888"
}'
```
### Crear Licencia para Tenant
```bash
curl -X POST http://localhost:8000/v1/licenses \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": 2,
"plan": "basic",
"max_users": 20,
"max_storage_gb": 50,
"max_monthly_operations": 10000,
"starts_at": "2025-10-17T00:00:00Z",
"expires_at": "2026-10-17T23:59:59Z"
}'
```
## Troubleshooting
### Error: "Connection refused" al llamar API
- Verificar que el backend esté corriendo: `docker-compose ps`
- Ver logs: `docker-compose logs backend`
- Reiniciar: `docker-compose restart backend`
### Error: "Tenant ID not found in token"
- Verificar que el usuario en Keycloak tenga el atributo `tenant_id` configurado
- Verificar que el mapper de Keycloak esté configurado correctamente
### Frontend muestra "Cargando" indefinidamente
- Abrir consola del navegador (F12) y revisar errores
- Verificar que Keycloak esté accesible: http://localhost:8080
- Verificar configuración en `frontend/.env`
### Base de datos vacía
- Ejecutar script de inicialización:
```bash
docker-compose exec backend python init_db.py
```
### Keycloak no responde
- Esperar unos minutos (puede tardar en iniciar)
- Ver logs: `docker-compose logs keycloak`
- Reiniciar: `docker-compose restart keycloak`
## Limpiar y Reiniciar
### Detener todo
```bash
docker-compose down
```
### Detener y eliminar volúmenes (borra BD)
```bash
docker-compose down -v
```
### Reiniciar desde cero
```bash
docker-compose down -v
./start.sh
```
## Checklist de Verificación
- [ ] Backend responde en http://localhost:8000
- [ ] Frontend carga en http://localhost:5173
- [ ] Keycloak accesible en http://localhost:8080
- [ ] Documentación API visible en http://localhost:8000/docs
- [ ] Login funciona correctamente
- [ ] Dashboard muestra información de usuario
- [ ] Dashboard muestra información de licencia
- [ ] Logout funciona correctamente
- [ ] API responde a peticiones con token válido
- [ ] API rechaza peticiones sin token
- [ ] Base de datos tiene tenant y licencia de prueba
## Próximos Pasos
Una vez que todas las pruebas pasen:
1. ✅ Revisar la documentación en `docs/ARCHITECTURE.md`
2. ✅ Explorar el código fuente de los módulos
3. ✅ Personalizar configuración según necesidades
4. ✅ Comenzar a desarrollar módulos adicionales
5. ✅ Configurar ambiente de producción
---
**¿Problemas?** Revisa los logs con `docker-compose logs -f` o abre un issue.
**¡Todo funciona!** 🎉 Estás listo para desarrollar sobre Anexo76.

70
docs/a76.json Normal file
View File

@@ -0,0 +1,70 @@
{
"context": {
"project_name": "Anexo76",
"description": "Aplicación SaaS para gestión de comercio exterior conforme a Anexos 24, 31 y 22 del SAT.",
"business_goal": "Ofrecer una plataforma multi-tenant para maquilas, IMMEX y agentes aduanales que permita manejar inventarios, pedimentos y facturas de importación/exportación con control de licencias y cumplimiento normativo."
},
"architecture": {
"frontend": {
"framework": "SvelteKit",
"auth_integration": "keycloak-js",
"ui_goal": "Dashboard moderno, responsivo y rápido para usuarios empresariales."
},
"backend": {
"framework": "FastAPI",
"auth": "Keycloak (OpenID Connect)",
"db_model": "Hybrid multi-tenant",
"shared_db": "Base de datos central para clientes pequeños y medianos",
"dedicated_db": "Bases de datos independientes para clientes grandes o con alta operación",
"features": [
"Conexión dinámica a BD según tenant",
"Middleware para validar licencias y tenants",
"APIs RESTful versionadas (v1, v2...)",
"Separación de capas: models (ORM), dto (Pydantic), service y routes"
],
"module_structure": {
"pattern": "backend/v1/modules/{module_name}/",
"files": {
"models.py": "Definición ORM con SQLAlchemy",
"dto.py": "Definición de Pydantic DTOs para entrada/salida de datos (reemplaza schemas.py)",
"service.py": "Lógica de negocio y validaciones específicas del módulo",
"routes.py": "Endpoints FastAPI que usan los DTOs y servicios"
},
"naming_convention": {
"models": "Representan entidades persistentes (Base de datos)",
"dto": "Data Transfer Objects para transporte entre capas y API",
"service": "Capa de negocio (domain logic)",
"routes": "Exposición HTTP / API layer"
},
"reasoning": "Se utiliza dto.py en lugar de schemas.py para reflejar un enfoque DDD y estilo arquitectónico similar a NestJS, manteniendo compatibilidad total con FastAPI y Pydantic."
}
},
"auth_system": {
"provider": "Keycloak",
"multi_tenant_model": "Un Realm por cliente (tenant)",
"roles": ["admin", "user", "auditor", "system"],
"license_validation": "Middleware que verifica licencia y plan activo antes de procesar cada request"
}
},
"license_management": {
"strategy": "Control centralizado en core_db",
"table_structure": {
"tenant_id": "int",
"plan": "string",
"max_users": "int",
"expires_at": "datetime",
"status": "active|expired|pending"
},
"upgrade_flow": "El cliente puede escalar de BD compartida a BD dedicada manteniendo mismo tenant_id y realm."
},
"dev_ops": {
"containerization": "Docker / Docker Compose",
"orchestration": "Kubernetes (futuro)",
"monitoring": ["Prometheus", "Grafana"],
"ci_cd": "GitHub Actions o GitLab CI"
},
"prompt_usage": {
"instruction": "Cuando uses este JSON, pide a la IA que genere o revise la arquitectura, código base o estrategia de despliegue respetando el modelo híbrido multi-tenant con Keycloak y FastAPI.",
"example_request": "Diseña un flujo de autenticación multi-tenant con Keycloak y FastAPI que detecte automáticamente el tenant y seleccione la base de datos correcta. Usa dto.py en lugar de schemas.py para mantener una arquitectura estilo DDD."
}
}