all(), [ 'name' => 'required|string|max:255|regex:/^[\pL\s\-]+$/u', 'email' => 'required|email|unique:postulantes,email|max:255', 'password' => [ 'required', 'string', 'min:8', 'confirmed', 'regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/' ], 'dni' => 'required|string|max:20|unique:postulantes,dni', ], [ 'password.regex' => 'La contraseña debe contener al menos una mayúscula, una minúscula, un número y un carácter especial.', 'name.regex' => 'El nombre solo puede contener letras y espacios.', ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()], 422); } $postulante = Postulante::create([ 'name' => strip_tags(trim($request->name)), 'email' => strtolower(trim($request->email)), 'password' => $request->password, 'dni' => $request->dni, ]); Log::info('Postulante registrado', ['id' => $postulante->id, 'dni' => $postulante->dni]); return response()->json(['success' => true, 'message' => 'Postulante registrado exitosamente', 'postulante' => $postulante], 201); } public function login(Request $request) { $validator = Validator::make($request->all(), [ 'email' => 'required|email|max:255', 'password' => 'required|string', ]); if ($validator->fails()) { return response()->json(['success' => false, 'errors' => $validator->errors()], 422); } $email = strtolower(trim($request->email)); $postulante = Postulante::where('email', $email)->first(); if (!$postulante || !Hash::check($request->password, $postulante->password)) { Log::warning('Intento de login fallido', ['email' => $email]); return response()->json([ 'success' => false, 'message' => 'Credenciales inválidas' ], 401); } $deviceId = $request->header('Device-Id') ?? Str::random(10); // Revocar tokens antiguos $postulante->tokens()->delete(); // Crear token $token = $postulante ->createToken($deviceId, ['*'], now()->addHour()) ->plainTextToken; $postulante->update([ 'device_id' => $deviceId, 'last_activity' => now() ]); Log::info('Login exitoso', ['id' => $postulante->id]); return response()->json([ 'success' => true, 'message' => 'Login exitoso', 'postulante' => [ 'id' => $postulante->id, 'name' => $postulante->name, 'email' => $postulante->email, 'dni' => $postulante->dni ], 'token' => $token, 'token_type' => 'Bearer', 'expires_in' => 3600 ]); } /** * Logout */ public function logout(Request $request) { $postulante = $request->user(); if ($postulante) { $postulante->tokens()->delete(); $postulante->device_id = null; $postulante->last_activity = null; $postulante->save(); } return response()->json(['success' => true, 'message' => 'Sesión cerrada correctamente']); } /** * Información del postulante logueado */ public function me(Request $request) { $postulante = $request->user(); if (!$postulante) { return response()->json(['success' => false, 'message' => 'No autenticado'], 401); } // Actualizar última actividad al hacer request $postulante->update(['last_activity' => now()]); return response()->json([ 'success' => true, 'postulante' => [ 'id' => $postulante->id, 'name' => $postulante->name, 'email' => $postulante->email, 'dni' => $postulante->dni ] ]); } public function obtenerPagosPostulante(Request $request) { $postulante = $request->user(); // o Auth::guard('postulante')->user(); if (!$postulante) { return response()->json([ 'success' => false, 'message' => 'No autenticado' ], 401); } $dni = trim($postulante->dni); $pagos = []; // =============================== // 1️⃣ PAGOS PYTO PERÚ // =============================== $urlPyto = "https://service2.unap.edu.pe/PAYMENTS_MNG/v1/{$dni}/8/"; $responsePyto = Http::get($urlPyto); if ($responsePyto->successful()) { $dataPyto = $responsePyto->json(); if (!empty($dataPyto['data'])) { foreach ($dataPyto['data'] as $pago) { $pagos[] = [ 'tipo' => 'pyto_peru', 'codigo' => $pago['autorizationCode'] ?? null, 'monto' => $pago['total'] ?? null, 'fecha_pago' => $pago['confirmedDate'] ?? null, 'estado' => true, 'raw' => $pago // devuelve toda la info original ]; } } } // =============================== // 2️⃣ PAGOS CAJA // =============================== $urlCaja = "https://inscripciones.admision.unap.edu.pe/api/get-pagos-caja-dni/{$dni}"; $responseCaja = Http::get($urlCaja); if ($responseCaja->successful()) { $dataCaja = $responseCaja->json(); if (!empty($dataCaja)) { foreach ($dataCaja as $pago) { $pagos[] = [ 'tipo' => 'caja', 'codigo' => $pago['paymentTitle'] ?? null, 'monto' => $pago['paymentAmount'] ?? null, 'fecha_pago' => $pago['paymentDatetime'] ?? null, 'estado' => true, 'raw' => $pago ]; } } } // =============================== // 3️⃣ BANCO NACIÓN // =============================== $urlBanco = 'https://inscripciones.admision.unap.edu.pe/api/get-pagos-banco-dni'; $responseBanco = Http::post($urlBanco, [ 'dni' => $dni, ]); if ($responseBanco->successful()) { $dataBanco = $responseBanco->json(); if (!empty($dataBanco['datos'])) { foreach ($dataBanco['datos'] as $pago) { $pagos[] = [ 'tipo' => 'banco_nacion', 'codigo' => $pago['secuencia'] ?? null, 'monto' => $pago['imp_pag'] ?? null, 'fecha_pago' => $pago['fch_pag'] ?? null, 'estado' => true, 'raw' => $pago ]; } } } return response()->json([ 'success' => true, 'postulante' => [ 'id' => $postulante->id, 'name' => $postulante->name, 'dni' => $dni, 'email' => $postulante->email, ], 'total_pagos' => count($pagos), 'pagos' => $pagos ]); } public function misProcesos(Request $request) { $dni = $request->user()->dni; $procesos = ResultadoAdmision::select( 'procesos_admision.id', 'procesos_admision.nombre', 'resultados_admision.puntaje', 'resultados_admision.apto' ) ->join('procesos_admision', 'procesos_admision.id', '=', 'resultados_admision.idproceso') ->where('resultados_admision.dni', $dni) ->distinct() ->get(); return response()->json([ 'success' => true, 'data' => $procesos ]); } }