queryService->listFamiliesByStudent($studentId); return $this->success([ 'families' => FamilyResource::collection($rows), ]); } public function guardiansByFamily(GuardiansByFamilyRequest $request, int $familyId): JsonResponse { $rows = $this->queryService->listGuardiansByFamily($familyId); return $this->success([ 'guardians' => FamilyGuardianResource::collection($rows), ]); } public function bootstrap(FamilyBootstrapRequest $request): JsonResponse { try { $result = $this->mutationService->bootstrapFamilies(); } catch (\Throwable $e) { Log::error('Family bootstrap failed: '.$e->getMessage()); return $this->error('Family bootstrap failed.', Response::HTTP_INTERNAL_SERVER_ERROR); } return $this->success($result, 'Bootstrap completed.'); } public function attachSecondByUser(FamilyAttachSecondByUserRequest $request): JsonResponse { $payload = $request->validated(); $result = $this->mutationService->attachSecondByUser( (int) $payload['student_id'], (int) $payload['user_id'], (string) ($payload['relation'] ?? 'secondary') ); if (! ($result['ok'] ?? false)) { return $this->error($result['message'] ?? 'Unable to attach guardian.', Response::HTTP_UNPROCESSABLE_ENTITY); } return $this->success($result, 'Guardian attached.'); } public function attachSecondByEmail(FamilyAttachSecondByEmailRequest $request): JsonResponse { $payload = $request->validated(); try { $result = $this->mutationService->attachSecondByEmail( (int) $payload['student_id'], (string) $payload['email'], $payload['firstname'] ?? null, $payload['lastname'] ?? null, (string) ($payload['relation'] ?? 'secondary') ); } catch (\Throwable $e) { Log::error('Attach guardian by email failed: '.$e->getMessage()); return $this->error('Unable to attach guardian.', Response::HTTP_INTERNAL_SERVER_ERROR); } if (! ($result['ok'] ?? false)) { return $this->error($result['message'] ?? 'Unable to attach guardian.', Response::HTTP_UNPROCESSABLE_ENTITY); } return $this->success($result, 'Guardian attached.'); } public function setPrimaryHome(FamilySetPrimaryHomeRequest $request): JsonResponse { $payload = $request->validated(); $this->mutationService->setPrimaryHome( (int) $payload['family_id'], (int) $payload['student_id'], (bool) $payload['is_primary_home'] ); return $this->success(null, 'Primary home updated.'); } public function setGuardianFlags(FamilySetGuardianFlagsRequest $request): JsonResponse { $payload = $request->validated(); $flags = array_intersect_key($payload, array_flip(['receive_emails', 'is_primary', 'receive_sms', 'relation'])); if (empty($flags)) { return $this->error('No flags provided.', Response::HTTP_UNPROCESSABLE_ENTITY); } $this->mutationService->setGuardianFlags( (int) $payload['family_id'], (int) $payload['user_id'], $flags ); return $this->success(null, 'Guardian flags updated.'); } public function unlinkGuardian(FamilyUnlinkGuardianRequest $request): JsonResponse { $payload = $request->validated(); $this->mutationService->unlinkGuardian( (int) $payload['family_id'], (int) $payload['user_id'] ); return $this->success(null, 'Guardian unlinked.'); } public function unlinkStudent(FamilyUnlinkStudentRequest $request): JsonResponse { $payload = $request->validated(); $this->mutationService->unlinkStudent( (int) $payload['family_id'], (int) $payload['student_id'] ); return $this->success(null, 'Student unlinked.'); } public function importSecondParentsFromLegacy(FamilyImportLegacyRequest $request): JsonResponse { try { $result = $this->mutationService->importSecondParentsFromLegacy(); } catch (\Throwable $e) { Log::error('Legacy second parent import failed: '.$e->getMessage()); return $this->error('Legacy import failed.', Response::HTTP_INTERNAL_SERVER_ERROR); } if (! ($result['ok'] ?? true)) { return $this->error($result['message'] ?? 'Legacy import failed.', Response::HTTP_UNPROCESSABLE_ENTITY); } return $this->success($result, 'Legacy import completed.'); } }