71 lines
1.7 KiB
Markdown
71 lines
1.7 KiB
Markdown
# ADR-004: Estrategia de Validación en 3 Capas
|
|
|
|
**Estado:** Aceptado
|
|
**Fecha:** 2026-01-07
|
|
|
|
## Contexto
|
|
|
|
Las reglas de negocio críticas son:
|
|
- Máximo 3 materias por estudiante (9 créditos)
|
|
- No repetir profesor en inscripciones
|
|
- Datos de entrada válidos (email, nombre)
|
|
|
|
## Decisión
|
|
|
|
Validar en **3 capas** con responsabilidades distintas:
|
|
|
|
| Capa | Responsabilidad | Tecnología |
|
|
|------|-----------------|------------|
|
|
| Frontend | UX, feedback rápido | Reactive Forms |
|
|
| Application | Estructura de datos, sanitización | FluentValidation |
|
|
| Domain | Reglas de negocio puras | Domain Services |
|
|
|
|
## Implementación
|
|
|
|
### Frontend (UX)
|
|
```typescript
|
|
this.form = this.fb.group({
|
|
name: ['', [Validators.required, Validators.minLength(3)]],
|
|
email: ['', [Validators.required, Validators.email]],
|
|
});
|
|
```
|
|
|
|
### Application (Sanitización + XSS)
|
|
```csharp
|
|
RuleFor(x => x.Name)
|
|
.NotEmpty()
|
|
.Must(NotContainDangerousContent); // Previene XSS
|
|
```
|
|
|
|
### Domain (Negocio)
|
|
```csharp
|
|
public void ValidateEnrollment(Student student, Subject subject)
|
|
{
|
|
if (student.Enrollments.Count >= 3)
|
|
throw new MaxEnrollmentsExceededException();
|
|
|
|
if (student.HasProfessor(subject.ProfessorId))
|
|
throw new SameProfessorConstraintException();
|
|
}
|
|
```
|
|
|
|
## Consecuencias
|
|
|
|
### Positivas
|
|
- Defensa en profundidad
|
|
- Separación de responsabilidades
|
|
- UX mejorada (errores rápidos)
|
|
- Seguridad garantizada (backend siempre valida)
|
|
|
|
### Negativas
|
|
- Duplicación parcial de reglas
|
|
- Mantener sincronizadas las validaciones
|
|
|
|
## Regla de Oro
|
|
|
|
> **Nunca confíes en el frontend.** El backend SIEMPRE debe validar.
|
|
|
|
## Referencias
|
|
|
|
- [OWASP Input Validation](https://owasp.org/www-community/Input_Validation)
|