Entidades
El proyecto implementa un sistema de entidades con auditoría y relaciones jerárquicas para gestionar usuarios, roles y privilegios.
Entidad Base de Auditoría
La clase AuditEntity
proporciona campos de auditoría comunes para todas las entidades:
@Getter
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditEntity {
@CreatedDate
private LocalDateTime createdAt; // Fecha de creación
@LastModifiedDate
private LocalDateTime updatedAt; // Fecha de última modificación
@CreatedBy
private User createdBy; // Usuario que creó el registro
}
Entidad Usuario (User)
La entidad principal que representa un usuario en el sistema:
@Entity
@Table(name = "users")
public class User extends AuditEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // ID interno
@Column(unique = true)
private UUID uuid; // ID público
private String firstName; // Nombre
private String lastName; // Apellido
@Column(unique = true)
private String email; // Email único
private String password; // Contraseña hasheada
@ManyToMany
@JoinTable(name = "user_roles")
private Collection<Role> roles; // Roles asignados
}
Características:
- Hereda campos de auditoría
- UUID autogenerado para referencias públicas
- Email único como identificador de usuario
- Relación muchos a muchos con roles
Entidad Rol (Role)
Define los roles que pueden ser asignados a usuarios:
@Entity
@Table(name = "roles")
public class Role {
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private UUID uuid;
@Enumerated(EnumType.STRING)
private RoleName name; // USER, ADMIN
@ManyToMany(mappedBy = "roles")
private Collection<User> users; // Usuarios con este rol
@ManyToMany
@JoinTable(name = "role_privileges")
private Collection<Privilege> privileges; // Privilegios del rol
}
public enum RoleName {
USER, // Usuario regular
ADMIN // Administrador
}
Entidad Privilegio (Privilege)
Define permisos específicos que pueden ser asignados a roles:
@Entity
@Table(name = "privileges")
public class Privilege {
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private UUID uuid;
@Enumerated(EnumType.STRING)
private PrivilegeName name; // READ, WRITE, DELETE
@ManyToMany(mappedBy = "privileges")
private Collection<Role> roles; // Roles con este privilegio
}
enum PrivilegeName {
READ, // Permiso de lectura
WRITE, // Permiso de escritura
DELETE // Permiso de eliminación
}
Diagrama de Relaciones
Mejores Prácticas
-
Auditoría:
- Todas las entidades principales heredan de
AuditEntity
- Seguimiento automático de fechas y usuario creador
- Campos de auditoría no modificables manualmente
- Todas las entidades principales heredan de
-
UUIDs:
- Usar UUID para referencias públicas
- ID numérico solo para referencias internas
- UUIDs autogenerados por PostgreSQL
-
Relaciones:
- Usar
@ToString.Exclude
para evitar referencias circulares - Nombrar tablas de unión descriptivamente
- Mantener la consistencia en las relaciones bidireccionales
- Usar
-
Validaciones:
- Usar anotaciones de validación de Jakarta
- Campos únicos marcados con
unique = true
- Campos requeridos marcados con
nullable = false