Skip to main content

User Management

DentControl’s user management system allows you to create and manage users with different roles across multiple dental clinics. Users are associated with specific clinics and have role-based permissions.

User Model Overview

The Usuario model (app/Models/Usuario.php) extends Laravel’s authentication system with custom fields for dental clinic management.

User Structure

Key Fields
protected $fillable = [
    'id_clinica',          // Associated clinic
    'nombre',              // First name
    'apellido_paterno',    // Paternal surname
    'apellido_materno',    // Maternal surname (optional)
    'cedula_profesional',  // Professional license (for dentists)
    'nom_usuario',         // Username (unique)
    'password',            // Hashed password
    'rol',                 // User role
    'estatus'              // Active/inactive status
];

User Roles

DentControl supports three user roles:
RoleDescriptionPermissions
superadminSystem administratorFull access to all clinics and system settings
dentistaDentist/DoctorManage patients, appointments, treatments in their clinic
asistenteAssistantLimited access to support dentists
Roles are defined as enum values in the database: superadmin, dentista, asistente.

Creating Users

Users can be created through the admin interface or programmatically.

Through Admin Interface

The UsuarioController (app/Http/Controllers/Admin/UsuarioController.php) handles user creation.
1

Access user management

Navigate to the admin panel and select “Usuarios” (Users).
2

Click create user

Click the “Nuevo Usuario” (New User) button to open the creation form.
3

Fill user details

Provide the required information:
  • Clínica: Select the clinic to associate the user with
  • Nombre: First name (min 3 letters, only letters and spaces)
  • Apellido Paterno: Paternal surname (required)
  • Apellido Materno: Maternal surname (optional)
  • Usuario: Username (4-20 alphanumeric characters, unique)
  • Contraseña: Password (see requirements below)
  • Rol: Select role (dentista or asistente)
  • Cédula Profesional: Professional license (required for dentists, 7-10 digits)
4

Submit

Click “Guardar” to create the user.

Password Requirements

DentControl enforces strong password policies:
Password::min(8)      // Minimum 8 characters
    ->letters()       // At least one letter
    ->mixedCase()     // Both uppercase and lowercase
    ->numbers()       // At least one number
Passwords are automatically hashed using bcrypt. Never store plain text passwords!

Programmatic User Creation

You can create users programmatically using the Usuario model:
use App\Models\Usuario;

Usuario::create([
    'id_clinica' => 1,
    'nombre' => 'Juan',
    'apellido_paterno' => 'García',
    'apellido_materno' => 'López',
    'nom_usuario' => 'jgarcia',
    'password' => 'SecurePass123', // Automatically hashed
    'rol' => 'dentista',
    'cedula_profesional' => '1234567',
    'estatus' => 'activo'
]);
The Usuario model uses the 'password' => 'hashed' cast, which automatically hashes passwords using bcrypt when saving.

Assigning Roles

Roles are assigned during user creation and can be updated later.

Role Assignment Rules

  1. Dentista role:
    • Requires cedula_profesional (professional license)
    • Can manage patients and treatments
    • Creates appointments and clinical notes
  2. Asistente role:
    • No professional license required
    • Supports dentists with administrative tasks
    • Limited clinical access
  3. Superadmin role:
    • Cannot be changed or suspended through the interface
    • Protected from accidental modifications
    • Full system access
The superadmin role is protected. The controller prevents editing or suspending superadmin users:
if ($usuario->rol === 'superadmin') {
    return redirect()->back()
        ->with('error', 'El Superadministrador no puede ser suspendido.');
}

Associating Users with Clinics

Every user must be associated with a clinic through the id_clinica foreign key.

Clinic Relationship

Usuario Model Relationship
public function clinica()
{
    return $this->belongsTo(Clinica::class, 'id_clinica', 'id_clinica');
}

Accessing User’s Clinic

$usuario = Usuario::find(1);
$clinica = $usuario->clinica;

echo $clinica->nombre; // Clinic name

User Status Management

Users can be activated or deactivated without deleting their records.

Status Values

  • activo: User can log in and access the system
  • baja: User is suspended and cannot log in

Toggle User Status

The toggleStatus method (app/Http/Controllers/Admin/UsuarioController.php:91) handles status changes:
1

Find the user

Locate the user in the admin panel user list.
2

Click status toggle

Click the status toggle button (usually a switch or button).
3

Confirm change

The system will toggle between activo and baja.
public function toggleStatus($id)
{
    $usuario = Usuario::findOrFail($id);

    // Protect superadmin
    if ($usuario->rol === 'admin') {
        return redirect()->back()
            ->with('error', 'El Superadministrador no puede ser suspendido.');
    }
    
    // Toggle status
    $nuevoEstado = ($usuario->estatus == 'activo') ? 'baja' : 'activo';
    $usuario->update(['estatus' => $nuevoEstado]);

    $mensaje = ($nuevoEstado == 'activo') 
        ? "El usuario {$usuario->nom_usuario} ha sido reactivado." 
        : "El acceso de {$usuario->nom_usuario} ha sido suspendido.";
    
    return redirect()->back()->with('success', $mensaje);
}

Updating Users

Users can be edited to update their information.

Editable Fields

  • Personal information (name, surnames)
  • Username (must remain unique)
  • Password (optional - only if changing)
  • Role (except for superadmin)
  • Professional license
  • Associated clinic

Update Process

1

Load user data

The edit method returns user data as JSON for the edit form:
public function edit($id)
{
    $usuario = Usuario::findOrFail($id);
    return response()->json($usuario);
}
2

Modify fields

Update the desired fields in the edit form.
3

Submit changes

The update method validates and saves changes:
  • Validates all fields
  • Only updates password if provided
  • Protects superadmin role from changes
public function update(Request $request, $id)
{
    $usuario = Usuario::findOrFail($id);

    // Protect superadmin role
    if ($usuario->rol === 'superadmin') {
        $request->merge(['rol' => 'superadmin']);
    }
    
    $rules = [
        'nombre' => 'required|string|min:3|max:255',
        'apellido_paterno' => 'required|string|min:3|max:255',
        'nom_usuario' => 'required|unique:usuario,nom_usuario,' . $id . ',id_usuario',
        'rol' => 'required|in:superadmin,dentista,asistente',
    ];

    // Only validate password if provided
    if ($request->filled('password')) {
        $rules['password'] = Password::min(8)->letters()->mixedCase()->numbers();
    }

    $validated = $request->validate($rules);
    
    // Don't update password if empty
    if (!$request->filled('password')) {
        unset($validated['password']);
    }

    $usuario->update($validated);

    return redirect()->route('usuarios.index')
        ->with('success', 'Usuario actualizado correctamente.');
}
When updating a user, the password field is optional. If left empty, the password won’t be changed.

User Relationships

The Usuario model has several important relationships:

Clinic Relationship

public function clinica()
{
    return $this->belongsTo(Clinica::class, 'id_clinica', 'id_clinica');
}

Appointments (Citas)

public function citas()
{
    return $this->hasMany(Cita::class, 'id_usuario', 'id_usuario');
}

Clinical Notes

public function notasEvolucion()
{
    return $this->hasMany(NotasEvolucion::class, 'id_usuario', 'id_usuario');
}

Using Relationships

$usuario = Usuario::find(1);
$citas = $usuario->citas;

foreach ($citas as $cita) {
    echo "Cita: {$cita->fecha} - {$cita->hora}";
}

Authentication

The Usuario model extends Authenticatable for Laravel’s authentication system.

Custom Authentication Methods

Usuario Model
public function getAuthPassword()
{
    return $this->password; // Use custom password column
}

public function getAuthIdentifierName()
{
    return 'id_usuario'; // Use custom ID column
}

Login Example

use Illuminate\Support\Facades\Auth;

$credentials = [
    'nom_usuario' => 'jgarcia',
    'password' => 'SecurePass123'
];

if (Auth::attempt($credentials)) {
    // Authentication successful
    $user = Auth::user();
    return redirect()->intended('dashboard');
}

Troubleshooting

Common validation issues:
  1. Username already exists: Each username must be unique
  2. Password too weak: Must meet all requirements (8+ chars, mixed case, numbers)
  3. Name contains invalid characters: Only letters and spaces allowed
  4. Missing professional license: Required for dentista role
Check storage/logs/laravel.log for detailed validation errors.
Verify:
  1. User status is active:
    $usuario = Usuario::where('nom_usuario', 'username')->first();
    echo $usuario->estatus; // Should be 'activo'
    
  2. Password is correct: Test password hash:
    use Illuminate\Support\Facades\Hash;
    
    $usuario = Usuario::where('nom_usuario', 'username')->first();
    if (Hash::check('entered_password', $usuario->password)) {
        echo "Password correct";
    }
    
  3. User exists in database:
    php artisan tinker
    Usuario::where('nom_usuario', 'username')->first();
    
Ensure the Usuario model has the password cast:
protected $casts = [
    'password' => 'hashed',
];
This cast automatically hashes passwords when saving.
This is intentional! The system protects superadmin users from accidental changes.To modify a superadmin:
  1. Access the database directly
  2. Or remove the protection check in the controller (not recommended)
Update the clinic association:
$usuario = Usuario::find(5);
$usuario->update(['id_clinica' => 2]); // Move to clinic 2
Or through the admin interface by editing the user.

Best Practices

  1. Always use strong passwords: Enforce the built-in password requirements
  2. Regularly audit user access: Review active users and their roles
  3. Use status toggle instead of deletion: Preserve user history by deactivating
  4. Associate users correctly: Ensure users belong to the right clinic
  5. Protect superadmin accounts: Never expose superadmin credentials
  6. Log user actions: Track important user activities for security

Next Steps

Configuration

Configure your application environment

Database Setup

Learn about database structure and migrations

Build docs developers (and LLMs) love