fix first production issues
API CI/CD / Validate (composer + pint) (push) Failing after 1m11s
API CI/CD / Test (PHPUnit) (push) Failing after 2m30s
API CI/CD / Build frontend assets (push) Successful in 1m14s
API CI/CD / Security audit (push) Failing after 48s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped

This commit is contained in:
root
2026-07-10 03:43:50 -04:00
parent 02ba2fe6b6
commit e9c10ae376
11 changed files with 687 additions and 564 deletions
+74 -44
View File
@@ -132,25 +132,36 @@ class Student extends BaseModel
/**
* legacy: getNewStudentsWithParentsAndEmergency()
* Picks one emergency contact via MIN(...) with groupBy student.
* Aggregates emergency contacts by parent before joining, avoiding
* duplicate student rows and ONLY_FULL_GROUP_BY violations.
*/
public static function getNewStudentsWithParentsAndEmergency(): array
{
$emergencyContacts = DB::table('emergency_contacts')
->select([
'parent_id',
DB::raw('MIN(emergency_contact_name) AS emergency_name'),
DB::raw('MIN(relation) AS emergency_relationship'),
DB::raw('MIN(cellphone) AS emergency_phone'),
])
->groupBy('parent_id');
return DB::table('students')
->selectRaw('
students.*,
u.firstname AS parent_firstname,
u.lastname AS parent_lastname,
u.email AS parent_email,
u.cellphone AS parent_phone,
MIN(ec.emergency_contact_name) AS emergency_name,
MIN(ec.relation) AS emergency_relationship,
MIN(ec.cellphone) AS emergency_phone
')
->leftJoin('users as u', 'u.id', '=', 'students.parent_id')
->leftJoin('emergency_contacts as ec', 'ec.parent_id', '=', 'students.parent_id')
->leftJoinSub($emergencyContacts, 'ec', function ($join): void {
$join->on('ec.parent_id', '=', 'students.parent_id');
})
->select([
'students.*',
'u.firstname as parent_firstname',
'u.lastname as parent_lastname',
'u.email as parent_email',
'u.cellphone as parent_phone',
'ec.emergency_name',
'ec.emergency_relationship',
'ec.emergency_phone',
])
->where('students.is_new', 1)
->groupBy('students.id')
->orderBy('students.lastname', 'asc')
->orderBy('students.firstname', 'asc')
->get()
@@ -163,46 +174,65 @@ class Student extends BaseModel
*/
public static function getStudentsWithParentsAndEmergency(?string $schoolYear = null, ?int $isNew = null): array
{
$q = DB::table('students')
->selectRaw('
students.*,
u.firstname AS parent_firstname,
u.lastname AS parent_lastname,
u.email AS parent_email,
u.cellphone AS parent_phone,
MIN(ec.emergency_contact_name) AS emergency_name,
MIN(ec.relation) AS emergency_relationship,
MIN(ec.cellphone) AS emergency_phone
')
->leftJoin('users as u', 'u.id', '=', 'students.parent_id')
->leftJoin('emergency_contacts as ec', 'ec.parent_id', '=', 'students.parent_id');
$emergencyContacts = DB::table('emergency_contacts')
->select([
'parent_id',
DB::raw('MIN(emergency_contact_name) AS emergency_name'),
DB::raw('MIN(relation) AS emergency_relationship'),
DB::raw('MIN(cellphone) AS emergency_phone'),
])
->groupBy('parent_id');
$q = DB::table('students')
->leftJoin('users as u', 'u.id', '=', 'students.parent_id')
->leftJoinSub($emergencyContacts, 'ec', function ($join): void {
$join->on('ec.parent_id', '=', 'students.parent_id');
})
->select([
'students.*',
'u.firstname as parent_firstname',
'u.lastname as parent_lastname',
'u.email as parent_email',
'u.cellphone as parent_phone',
'ec.emergency_name',
'ec.emergency_relationship',
'ec.emergency_phone',
]);
// is_new filter
if ($isNew === 0 || $isNew === 1) {
$q->where('students.is_new', $isNew);
} else {
$q->whereIn('students.is_new', [0, 1]);
}
// Students are global identities; year rosters come from yearly class/enrollment rows.
if ($schoolYear !== null && strtolower($schoolYear) !== 'all') {
$q->where(function ($yearQuery) use ($schoolYear) {
$yearQuery->whereExists(function ($sub) use ($schoolYear) {
$sub->selectRaw('1')
->from('student_class as sc')
->whereColumn('sc.student_id', 'students.id')
->where('sc.school_year', $schoolYear);
})->orWhereExists(function ($sub) use ($schoolYear) {
$sub->selectRaw('1')
->from('enrollments as e')
->whereColumn('e.student_id', 'students.id')
->where('e.school_year', $schoolYear);
});
$normalizedSchoolYear = $schoolYear !== null
? trim($schoolYear)
: null;
if (
$normalizedSchoolYear !== null
&& $normalizedSchoolYear !== ''
&& strtolower($normalizedSchoolYear) !== 'all'
) {
$q->where(function ($yearQuery) use ($normalizedSchoolYear): void {
$yearQuery
->whereExists(function ($sub) use ($normalizedSchoolYear): void {
$sub->selectRaw('1')
->from('student_class as sc')
->whereColumn('sc.student_id', 'students.id')
->where('sc.school_year', $normalizedSchoolYear);
})
->orWhereExists(function ($sub) use ($normalizedSchoolYear): void {
$sub->selectRaw('1')
->from('enrollments as e')
->whereColumn('e.student_id', 'students.id')
->where('e.school_year', $normalizedSchoolYear);
});
});
}
return $q->groupBy('students.id')
->orderByDesc('students.is_new') // new first
return $q
->orderByDesc('students.is_new')
->orderBy('students.lastname', 'asc')
->orderBy('students.firstname', 'asc')
->get()
@@ -403,4 +433,4 @@ class Student extends BaseModel
'is_active' => ['nullable', 'boolean'],
];
}
}
}