fix unit tests as well as missing code
API CI/CD / Validate (composer + pint) (push) Successful in 2m7s
API CI/CD / Test (PHPUnit) (push) Failing after 2m23s
API CI/CD / Build frontend assets (push) Successful in 2m18s
API CI/CD / Security audit (push) Successful in 31s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped

This commit is contained in:
root
2026-06-25 14:26:32 -04:00
parent fdfcd1f0e2
commit 940afe9319
115 changed files with 4554 additions and 290 deletions
@@ -104,6 +104,10 @@ class GradingController extends BaseApiController
return $userId;
}
if (! $this->currentUserHasAnyRole(['teacher', 'administrator', 'admin'])) {
return response()->json(['ok' => false, 'message' => 'Forbidden.'], 403);
}
$payload = $request->validated();
$locked = $this->lockService->toggle(
(int) $payload['class_section_id'],
@@ -122,6 +126,10 @@ class GradingController extends BaseApiController
return $userId;
}
if (! $this->currentUserHasAnyRole(['teacher', 'administrator', 'admin'])) {
return response()->json(['ok' => false, 'message' => 'Forbidden.'], 403);
}
$payload = $request->validated();
$count = $this->lockService->lockAll(
(string) $payload['semester'],
@@ -213,7 +221,11 @@ class GradingController extends BaseApiController
public function showPlacementBatch(int $batchId): JsonResponse
{
$data = $this->placementService->getPlacementBatch($batchId);
try {
$data = $this->placementService->getPlacementBatch($batchId);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 404);
}
return response()->json(['ok' => true] + $data);
}
@@ -226,12 +238,18 @@ class GradingController extends BaseApiController
}
$payload = $request->validated();
$this->placementService->updatePlacementBatch(
$batchId,
(string) $payload['school_year'],
$payload['placement_level'] ?? [],
$userId
);
try {
$this->placementService->updatePlacementBatch(
$batchId,
(string) $payload['school_year'],
$payload['placement_level'] ?? [],
$userId
);
} catch (\RuntimeException $e) {
$status = str_contains(strtolower($e->getMessage()), 'not found') ? 404 : 422;
return response()->json(['ok' => false, 'message' => $e->getMessage()], $status);
}
return response()->json(['ok' => true]);
}
@@ -255,11 +273,15 @@ class GradingController extends BaseApiController
public function belowSixtyEmail(BelowSixtyEmailRequest $request): JsonResponse
{
$payload = $request->validated();
$data = $this->belowSixtyService->emailContext(
(int) $payload['student_id'],
(string) $payload['school_year'],
(string) $payload['semester']
);
try {
$data = $this->belowSixtyService->emailContext(
(int) $payload['student_id'],
(string) $payload['school_year'],
(string) $payload['semester']
);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
return response()->json(['ok' => true] + $data);
}
@@ -267,11 +289,15 @@ class GradingController extends BaseApiController
public function sendBelowSixtyEmail(BelowSixtySendRequest $request): JsonResponse
{
$payload = $request->validated();
$data = $this->belowSixtyService->emailContext(
(int) $payload['student_id'],
(string) $payload['school_year'],
(string) $payload['semester']
);
try {
$data = $this->belowSixtyService->emailContext(
(int) $payload['student_id'],
(string) $payload['school_year'],
(string) $payload['semester']
);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
$subject = trim((string) ($payload['subject'] ?? ''));
if ($subject !== '') {
@@ -334,7 +360,11 @@ class GradingController extends BaseApiController
}
$payload = $request->validated();
$count = $this->belowSixtyService->generateAllDecisions((string) $payload['school_year'], $userId);
try {
$count = $this->belowSixtyService->generateAllDecisions((string) $payload['school_year'], $userId);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
return response()->json(['ok' => true, 'saved_count' => $count]);
}
@@ -385,10 +415,14 @@ class GradingController extends BaseApiController
public function belowSixtyDecisionEmail(BelowSixtyDecisionDetailsRequest $request): JsonResponse
{
$payload = $request->validated();
$data = $this->belowSixtyService->decisionEmailContext(
(int) $payload['student_id'],
(string) $payload['school_year']
);
try {
$data = $this->belowSixtyService->decisionEmailContext(
(int) $payload['student_id'],
(string) $payload['school_year']
);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
return response()->json(['ok' => true] + $data);
}
@@ -396,12 +430,16 @@ class GradingController extends BaseApiController
public function sendBelowSixtyDecisionEmail(BelowSixtyDecisionSendRequest $request): JsonResponse
{
$payload = $request->validated();
$this->belowSixtyService->sendDecisionEmail(
(int) $payload['student_id'],
(string) $payload['school_year'],
isset($payload['subject']) ? (string) $payload['subject'] : null,
isset($payload['html']) ? (string) $payload['html'] : null
);
try {
$this->belowSixtyService->sendDecisionEmail(
(int) $payload['student_id'],
(string) $payload['school_year'],
isset($payload['subject']) ? (string) $payload['subject'] : null,
isset($payload['html']) ? (string) $payload['html'] : null
);
} catch (\RuntimeException $e) {
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
}
return response()->json(['ok' => true]);
}
@@ -428,4 +466,24 @@ class GradingController extends BaseApiController
return $userId;
}
/**
* @param list<string> $roles
*/
private function currentUserHasAnyRole(array $roles): bool
{
$user = request()->user() ?? auth()->user();
if (! $user || ! method_exists($user, 'roles')) {
return false;
}
$roles = array_map('strtolower', $roles);
return $user->roles()
->where(function ($query) use ($roles) {
$query->whereIn('roles.name', $roles)
->orWhereIn('roles.slug', $roles);
})
->exists();
}
}