namespace SIGCM2.Domain.Entities; public sealed class Usuario { public int Id { get; } public string Username { get; } public string PasswordHash { get; } public string Nombre { get; } public string Apellido { get; } public string? Email { get; } public string Rol { get; } public string PermisosJson { get; } public bool Activo { get; } // UDT-008: new properties public DateTime? FechaModificacion { get; } public DateTime? UltimoLogin { get; } public bool MustChangePassword { get; } public Usuario( int id, string username, string passwordHash, string nombre, string apellido, string? email, string rol, string permisosJson, bool activo, DateTime? fechaModificacion = null, DateTime? ultimoLogin = null, bool mustChangePassword = false) { Id = id; Username = username; PasswordHash = passwordHash; Nombre = nombre; Apellido = apellido; Email = email; Rol = rol; PermisosJson = permisosJson; Activo = activo; FechaModificacion = fechaModificacion; UltimoLogin = ultimoLogin; MustChangePassword = mustChangePassword; } /// /// Factory for creating a new user (no Id — DB assigns via IDENTITY). /// Defaults: Activo=true, PermisosJson={"grant":[],"deny":[]}, MustChangePassword=false. /// public static Usuario ForCreation( string username, string passwordHash, string nombre, string apellido, string? email, string rol) { return new Usuario( id: 0, username: username, passwordHash: passwordHash, nombre: nombre, apellido: apellido, email: email, rol: rol, permisosJson: """{"grant":[],"deny":[]}""", activo: true, fechaModificacion: null, ultimoLogin: null, mustChangePassword: false); } // ── UDT-008: copy-with factory methods ──────────────────────────────────── /// /// Returns a new instance with updated profile fields. /// Sets FechaModificacion = UtcNow. Username and PasswordHash are immutable. /// public Usuario WithUpdatedProfile(string nombre, string apellido, string? email, string rol, bool activo) => new( id: Id, username: Username, passwordHash: PasswordHash, nombre: nombre, apellido: apellido, email: email, rol: rol, permisosJson: PermisosJson, activo: activo, fechaModificacion: DateTime.UtcNow, ultimoLogin: UltimoLogin, mustChangePassword: MustChangePassword); /// /// Returns a new instance with a new password hash and mustChangePassword flag. /// Sets FechaModificacion = UtcNow. /// public Usuario WithNewPasswordHash(string hash, bool mustChangePassword) => new( id: Id, username: Username, passwordHash: hash, nombre: Nombre, apellido: Apellido, email: Email, rol: Rol, permisosJson: PermisosJson, activo: Activo, fechaModificacion: DateTime.UtcNow, ultimoLogin: UltimoLogin, mustChangePassword: mustChangePassword); /// /// Returns a new instance with only the MustChangePassword flag changed. /// Sets FechaModificacion = UtcNow. /// public Usuario WithMustChangePassword(bool value) => new( id: Id, username: Username, passwordHash: PasswordHash, nombre: Nombre, apellido: Apellido, email: Email, rol: Rol, permisosJson: PermisosJson, activo: Activo, fechaModificacion: DateTime.UtcNow, ultimoLogin: UltimoLogin, mustChangePassword: value); /// /// UDT-009: Returns a new instance with PermisosJson replaced. /// Sets FechaModificacion = UtcNow. /// Accepts raw JSON string so Domain stays free of Application dependencies. /// public Usuario WithPermisosJson(string permisosJson) => new( id: Id, username: Username, passwordHash: PasswordHash, nombre: Nombre, apellido: Apellido, email: Email, rol: Rol, permisosJson: permisosJson, activo: Activo, fechaModificacion: DateTime.UtcNow, ultimoLogin: UltimoLogin, mustChangePassword: MustChangePassword); /// /// Returns a new instance with only UltimoLogin updated. /// Does NOT touch FechaModificacion. /// public Usuario WithUltimoLogin(DateTime utcNow) => new( id: Id, username: Username, passwordHash: PasswordHash, nombre: Nombre, apellido: Apellido, email: Email, rol: Rol, permisosJson: PermisosJson, activo: Activo, fechaModificacion: FechaModificacion, ultimoLogin: utcNow, mustChangePassword: MustChangePassword); }