Overview
ThePacienteController handles all patient-specific operations in NutriFit. It enables patients to book appointments with nutritionists, view their appointment history, access their clinical records, and manage their profile.
Namespace: App\Http\Controllers
Middleware: auth, verified, role:paciente, password.changed
Route Prefix: /paciente
Dashboard
index()
Displays the patient dashboard with statistics and appointment information.GET /paciente/dashboard
Route Name: paciente.dashboard
Returns: View with:
- Appointment statistics (total, completed, pending)
- Next appointment details
- Recent appointments (last 10)
- List of available nutritionists (clinically enabled only)
Appointment Booking
showBooking()
Displays the list of available nutritionists for booking.GET /paciente/agendar
Route Name: paciente.booking.index
Returns: View with list of clinically enabled nutritionists and their schedule counts
selectSchedule(User $nutricionista)
Displays available time slots for a specific nutritionist.GET /paciente/agendar/{nutricionista}
Route Name: paciente.booking.schedule
Parameters:
nutricionista(User): Route model binding
- 4 weeks of available time slots
- Nutritionist information
- Schedule grid grouped by weeks and days
- Nutritionist must be clinically enabled
- Patient cannot have pending appointments with ANY nutritionist
- Nutritionist must have configured schedules
- If nutritionist unavailable: redirect to booking index
- If patient has pending appointment: redirect to dashboard with error
- If nutritionist has no schedules: redirect to booking index
storeAppointment(Request nutricionista)
Creates a new appointment booking.POST /paciente/agendar/{nutricionista}
Route Name: paciente.booking.store
Parameters:
nutricionista(User): Route model bindingdate(date, required): Appointment date (must be today or future)time(string, required): Appointment time (HH:MM format)reason(string, optional): Reason for appointment (max 500 chars)appointment_type(string, required): Type (primera_vez,seguimiento,control)
- Creates appointment with “pendiente” state
- Sets price from nutritionist settings (default $30.00)
- Sends immediate notification to nutritionist
- Sends delayed notification to patient (20 seconds)
- Nutritionist must be clinically enabled
- Patient cannot have pending appointments
- Time slot must be available
- Schedule must exist for selected day and time
- Time must be within nutritionist’s configured schedule range
Appointment Management
appointments(Request $request)
Displays the patient’s appointment history with filtering.GET /paciente/citas
Route Name: paciente.appointments.index
Query Parameters:
estado(string, optional): Filter by appointment statenutricionista(integer, optional): Filter by nutritionist IDfecha_desde(date, optional): Start date filterfecha_hasta(date, optional): End date filter
showAppointment(Appointment $appointment)
Displays detailed information about a specific appointment.GET /paciente/citas/{appointment}
Route Name: paciente.appointments.show
Parameters:
appointment(Appointment): Route model binding
- Nutritionist information and personal data
- Appointment state
- Attention data (if completed)
- Patient personal data
cancelAppointment(Appointment $appointment)
Cancels a patient’s appointment.POST /paciente/citas/{appointment}/cancelar
Route Name: paciente.appointments.cancel
Parameters:
appointment(Appointment): Route model binding
- Updates appointment state to “cancelada”
- Sends immediate notification to patient
- Sends delayed notification to nutritionist (20 seconds)
Clinical History
history()
Displays the patient’s clinical history with progress charts.GET /paciente/historial
Route Name: paciente.history
Returns: View with:
- All attention records for the patient (all nutritionists)
- Chart data for visualization
- Progress statistics
- Patient personal data
- Weight progression over time
- BMI changes
- Body fat percentage
- All body circumferences (waist, hip, neck, wrist, arms, thighs, calves)
- Metabolic metrics (TMB, TDEE, target calories)
- Health ratios (WHR, WHT)
Profile Management
profile()
Displays the patient profile page.GET /paciente/perfil
Route Name: paciente.profile
Returns: Patient profile view
updatePassword(Request $request)
Updates the patient’s password.POST /paciente/perfil/contrasena
Route Name: paciente.profile.update-password
Parameters:
current_password(string, required if not default): Current passwordpassword(string, required): New password (min 8 chars)password_confirmation(string, required): Password confirmation
PasswordChangedNotification
Validation:
- If user has non-default password, current password is required and must match
- New password must be at least 8 characters
- Password confirmation must match new password
Private Helper Methods
prepareChartData($attentions)
Prepares attention data for Chart.js visualization.$attentions(Collection): Collection of Attention models with attentionData
calculateProgressStats($attentions)
Calculates progress statistics comparing first and last attention.$attentions(Collection): Collection of Attention models
- Total attentions count
- First and last attention dates
- Weight change (absolute and percentage)
- BMI change
- Body fat change
- All circumference changes
- Metabolic metrics changes (TMB, TDEE)
Business Rules
One Pending Appointment Rule
Patients can only have one pending appointment at a time (with any nutritionist). This prevents overbooking and ensures commitment. Enforced in:selectSchedule()- Before showing available slotsstoreAppointment()- Before creating appointment
Clinical Enablement
Patients can only book with nutritionists who are clinically enabled:- User account must be active (
user_state= “activo”) - Nutritionist must have configured schedules
$user->estaHabilitadoClinicamente() method
Time Slot Availability
Time slots are considered available when:- They are in the future (not past)
- They fall within nutritionist’s configured schedule
- No other pending appointment exists at that time
- Duration is 45 minutes per slot
Dependencies
The PacienteController uses: Models:App\Models\UserApp\Models\AppointmentApp\Models\AppointmentStateApp\Models\NutricionistaScheduleApp\Models\Attention
App\Notifications\AppointmentCancelledByPatientApp\Notifications\AppointmentCreatedNotificationApp\Notifications\AppointmentConfirmedForPatientApp\Notifications\PasswordChangedNotification
Carbon\Carbonfor date/time manipulationIlluminate\Support\Facades\Hashfor password hashing