This commit is contained in:
Laucha1312
2026-06-04 15:20:52 -03:00
parent cc049c6cb6
commit df828ddd7c
2 changed files with 257 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
<?php
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');
use Illuminate\Support\Facades\Schedule;
Schedule::command('app:cleanup-old-events')->daily();
// Frecuencia de backup configurable (con fallback seguro si DB no disponible)
try {
$backupFreq = \App\Models\Configuracion::get('backup_frequency', 'daily');
} catch (\Throwable $e) {
$backupFreq = 'daily';
}
Schedule::command('backup:run')->{$backupFreq}()->at('01:00');
Schedule::command('backup:clean')->{$backupFreq}()->at('02:00');
// Recordatorio de partidos: diariamente a las 9am
Schedule::command('notificaciones:recordatorio-partido')->dailyAt('09:00');
// Reporte semanal: lunes a las 8am
Schedule::command('reportes:semanal')->weeklyOn(1, '08:00');
// Purge de hilos de conversación del agente expirados
Schedule::command('agent:purge-threads')->dailyAt('03:00');
// Registro de salud del sistema: se ejecuta cada minuto para confirmar que el Cron Job funciona
Schedule::call(function () {
\App\Models\Configuracion::set('last_scheduler_run', now()->toDateTimeString(), 'Última ejecución detectada del programador');
})->everyMinute();
+220
View File
@@ -0,0 +1,220 @@
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\EquipoController;
use App\Http\Controllers\EventoController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\NoticiaController;
use App\Http\Controllers\PromocionController;
use App\Http\Controllers\PromoQrController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\PanelController;
use App\Http\Controllers\AdminController;
use App\Http\Controllers\NotificacionController;
use App\Http\Controllers\SeguimientoController;
use App\Http\Controllers\QrDownloadController;
use App\Http\Controllers\DocumentacionController;
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('/offline', fn() => view('offline'))->name('offline');
Route::get('/eventos', [EventoController::class, 'index'])->name('eventos.index');
Route::get('/eventos/{id}', [EventoController::class, 'show'])->name('eventos.show');
Route::get('/promos', [PromocionController::class, 'index'])->name('promos.index');
Route::get('/promos/{id}/qr', [PromoQrController::class, 'show'])->name('promo.qr');
Route::get('/asociate', function () { return view('auth.asociate'); })->name('asociate');
Route::get('/noticias', [NoticiaController::class, 'index'])->name('noticias.index');
Route::get('/noticias/{id}', [NoticiaController::class, 'show'])->name('noticias.show');
Route::get('/torneos/{id}/posiciones', [App\Http\Controllers\TorneoController::class, 'standings'])->name('torneos.standings');
Route::get('/torneos/{id}/goleadores', [App\Http\Controllers\TorneoController::class, 'topScorers'])->name('torneos.topScorers');
Route::get('/equipos/{id}', [EquipoController::class, 'publicShow'])->name('equipos.show');
Route::get('/documentacion', [DocumentacionController::class, 'index'])->name('documentacion.index');
Route::get('/documentacion/descargar', [DocumentacionController::class, 'download'])->name('documentacion.download');
Route::get('/panel-usuario', [PanelController::class, 'index'])->name('panel.usuario');
Route::post('/panel-usuario/actualizar', [PanelController::class, 'actualizarDatos'])->name('panel.actualizar');
Route::post('/panel-usuario/password', [PanelController::class, 'cambiarPassword'])->name('panel.password');
Route::post('/panel-usuario/solicitar-qr', [PanelController::class, 'solicitarQr'])->name('panel.solicitar.qr');
Route::get('/panel-usuario/mis-qrs', [PanelController::class, 'misQrs'])->name('panel.mis.qrs');
Route::get('/panel-usuario/qr/descargar/{id}', [QrDownloadController::class, 'download'])->name('panel.qr.descargar');
Route::post('/panel-usuario/generar-promo-qr', [PanelController::class, 'generarPromoQr'])->name('panel.generar.promo.qr');
Route::get('/panel-usuario/promo-qr/{id}', [PanelController::class, 'verPromoQr'])->name('panel.promo.qr.ver');
// // Notificaciones
Route::get('/notificaciones', [NotificacionController::class, 'index'])->name('notificaciones.index');
Route::get('/notificaciones/count', [NotificacionController::class, 'count'])->name('notificaciones.count');
Route::get('/notificaciones/latest', [NotificacionController::class, 'latest'])->name('notificaciones.latest');
Route::post('/notificaciones/subscribe', [NotificacionController::class, 'subscribe'])->name('notificaciones.subscribe');
Route::post('/notificaciones/{id}/leer', [NotificacionController::class, 'marcarLeida'])->name('notificaciones.leer');
Route::post('/notificaciones/leer-todas', [NotificacionController::class, 'marcarTodasLeidas'])->name('notificaciones.leer.todas');
Route::delete('/notificaciones/{id}', [NotificacionController::class, 'eliminar'])->name('notificaciones.eliminar');
Route::delete('/notificaciones', [NotificacionController::class, 'eliminarTodas'])->name('notificaciones.eliminar.todas');
// ─── Seguimiento de Equipos ───
Route::post('/seguimiento/equipo/{id}', [SeguimientoController::class, 'toggle'])->name('seguimiento.toggle');
Route::get('/seguimiento/mis-equipos', [SeguimientoController::class, 'misEquipos'])->name('seguimiento.mis.equipos');
Route::get('/seguimiento/estado/{id}', [SeguimientoController::class, 'estado'])->name('seguimiento.estado');
Route::get('/recuperar', function () { return view('auth.recuperar'); })->name('recuperar');
Route::get('/reset-password/{token}', [AuthController::class, 'resetPasswordForm'])->name('reset.password');
Route::get('/registro/jugador/buscar', fn() => redirect()->route('asociate'))->name('registro.jugador.buscar.get');
// Rate limiting en rutas críticas: 5 intentos por minuto
Route::middleware(['throttle:5,1'])->group(function () {
Route::post('/recuperar', [AuthController::class, 'recuperar']);
Route::post('/reset-password', [AuthController::class, 'resetPassword'])->name('reset.password.post');
Route::post('/login', [AuthController::class, 'login'])->name('login');
Route::post('/registro/aficionado', [AuthController::class, 'registroAficionado'])->name('registro.aficionado');
Route::post('/registro/jugador/buscar', [AuthController::class, 'buscarJugador'])->name('registro.jugador.buscar');
Route::post('/registro/jugador/completar', [AuthController::class, 'completarRegistroJugador'])->name('registro.jugador.completar');
});
Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
// ═══ ADMIN PANEL ═══
Route::redirect('/gestionar', '/admin');
Route::prefix('admin')->group(function () {
Route::get('/', [AdminController::class, 'dashboard'])->name('admin.dashboard');
// Clubes
Route::get('/clubes', [AdminController::class, 'clubesIndex'])->name('admin.clubes.index');
Route::get('/clubes/crear', [AdminController::class, 'clubesCreate'])->name('admin.clubes.create');
Route::post('/clubes', [AdminController::class, 'clubesStore'])->name('admin.clubes.store');
Route::get('/clubes/{id}/editar', [AdminController::class, 'clubesEdit'])->name('admin.clubes.edit');
Route::put('/clubes/{id}', [AdminController::class, 'clubesUpdate'])->name('admin.clubes.update');
Route::delete('/clubes/{id}', [AdminController::class, 'clubesDestroy'])->name('admin.clubes.destroy');
// Equipos
Route::get('/equipos', [AdminController::class, 'equiposIndex'])->name('admin.equipos.index');
Route::get('/equipos/crear', [AdminController::class, 'equiposCreate'])->name('admin.equipos.create');
Route::post('/equipos', [AdminController::class, 'equiposStore'])->name('admin.equipos.store');
Route::get('/equipos/{id}/editar', [AdminController::class, 'equiposEdit'])->name('admin.equipos.edit');
Route::put('/equipos/{id}', [AdminController::class, 'equiposUpdate'])->name('admin.equipos.update');
Route::delete('/equipos/{id}', [AdminController::class, 'equiposDestroy'])->name('admin.equipos.destroy');
Route::get('/equipos/{id}/jugadores', [AdminController::class, 'equipoJugadores'])->name('admin.equipos.jugadores');
Route::post('/equipos/{id}/jugadores', [AdminController::class, 'equipoAddJugador'])->name('admin.equipos.jugadores.add');
Route::delete('/equipos/{id}/jugadores/{id_jugador}', [AdminController::class, 'equipoRemoveJugador'])->name('admin.equipos.jugadores.remove');
Route::get('/jugadores/search-ajax', [AdminController::class, 'jugadoresSearchAjax'])->name('admin.jugadores.search.ajax');
Route::get('/jugadores/categoria-por-edad', [AdminController::class, 'jugadoresCategoriaPorEdad'])->name('admin.jugadores.categoria.edad');
// Jugadores
Route::get('/jugadores', [AdminController::class, 'jugadoresIndex'])->name('admin.jugadores.index');
Route::get('/jugadores/crear', [AdminController::class, 'jugadoresCreate'])->name('admin.jugadores.create');
Route::post('/jugadores', [AdminController::class, 'jugadoresStore'])->name('admin.jugadores.store');
Route::get('/jugadores/{id}/editar', [AdminController::class, 'jugadoresEdit'])->name('admin.jugadores.edit');
Route::put('/jugadores/{id}', [AdminController::class, 'jugadoresUpdate'])->name('admin.jugadores.update');
Route::delete('/jugadores/{id}', [AdminController::class, 'jugadoresDestroy'])->name('admin.jugadores.destroy');
Route::post('/jugadores/importar', [AdminController::class, 'jugadoresImport'])->name('admin.jugadores.import');
Route::get('/jugadores/exportar', [AdminController::class, 'jugadoresExport'])->name('admin.jugadores.export');
// Pases
Route::get('/pases', [\App\Http\Controllers\Admin\PaseController::class, 'index'])->name('admin.pases.index');
Route::get('/pases/crear', [\App\Http\Controllers\Admin\PaseController::class, 'create'])->name('admin.pases.create');
Route::post('/pases', [\App\Http\Controllers\Admin\PaseController::class, 'store'])->name('admin.pases.store');
Route::put('/pases/{id}/aprobar', [\App\Http\Controllers\Admin\PaseController::class, 'aprobar'])->name('admin.pases.aprobar');
Route::put('/pases/{id}/rechazar', [\App\Http\Controllers\Admin\PaseController::class, 'rechazar'])->name('admin.pases.rechazar');
// Categorias
Route::get('/categorias', [\App\Http\Controllers\Admin\CategoriaController::class, 'index'])->name('admin.categorias.index');
Route::get('/categorias/crear', [\App\Http\Controllers\Admin\CategoriaController::class, 'create'])->name('admin.categorias.create');
Route::post('/categorias', [\App\Http\Controllers\Admin\CategoriaController::class, 'store'])->name('admin.categorias.store');
Route::get('/categorias/{id}/editar', [\App\Http\Controllers\Admin\CategoriaController::class, 'edit'])->name('admin.categorias.edit');
Route::put('/categorias/{id}', [\App\Http\Controllers\Admin\CategoriaController::class, 'update'])->name('admin.categorias.update');
Route::delete('/categorias/{id}', [\App\Http\Controllers\Admin\CategoriaController::class, 'destroy'])->name('admin.categorias.destroy');
// Administradores
Route::get('/usuarios', [\App\Http\Controllers\Admin\AdminUserController::class, 'index'])->name('admin.usuarios.index');
Route::get('/usuarios/crear', [\App\Http\Controllers\Admin\AdminUserController::class, 'create'])->name('admin.usuarios.create');
Route::post('/usuarios', [\App\Http\Controllers\Admin\AdminUserController::class, 'store'])->name('admin.usuarios.store');
Route::get('/usuarios/{id}/editar', [\App\Http\Controllers\Admin\AdminUserController::class, 'edit'])->name('admin.usuarios.edit');
Route::put('/usuarios/{id}', [\App\Http\Controllers\Admin\AdminUserController::class, 'update'])->name('admin.usuarios.update');
Route::delete('/usuarios/{id}', [\App\Http\Controllers\Admin\AdminUserController::class, 'destroy'])->name('admin.usuarios.destroy');
// Eventos
Route::get('/eventos', [AdminController::class, 'eventosIndex'])->name('admin.eventos.index');
Route::get('/eventos/crear', [AdminController::class, 'eventosCreate'])->name('admin.eventos.create');
Route::post('/eventos', [AdminController::class, 'eventosStore'])->name('admin.eventos.store');
Route::get('/eventos/{id}/editar', [AdminController::class, 'eventosEdit'])->name('admin.eventos.edit');
Route::put('/eventos/{id}', [AdminController::class, 'eventosUpdate'])->name('admin.eventos.update');
Route::delete('/eventos/{id}', [AdminController::class, 'eventosDestroy'])->name('admin.eventos.destroy');
Route::get('/eventos/{id}/stats', [AdminController::class, 'eventosStats'])->name('admin.eventos.stats');
Route::post('/eventos/{id}/stats', [AdminController::class, 'eventosStatsStore'])->name('admin.eventos.stats.store');
// Promociones
Route::get('/promociones', [AdminController::class, 'promocionesIndex'])->name('admin.promociones.index');
Route::get('/promociones/crear', [AdminController::class, 'promocionesCreate'])->name('admin.promociones.create');
Route::post('/promociones', [AdminController::class, 'promocionesStore'])->name('admin.promociones.store');
Route::get('/promociones/{id}/editar', [AdminController::class, 'promocionesEdit'])->name('admin.promociones.edit');
Route::put('/promociones/{id}', [AdminController::class, 'promocionesUpdate'])->name('admin.promociones.update');
Route::delete('/promociones/{id}', [AdminController::class, 'promocionesDestroy'])->name('admin.promociones.destroy');
// Noticias
Route::get('/noticias', [AdminController::class, 'noticiasIndex'])->name('admin.noticias.index');
Route::get('/noticias/crear', [AdminController::class, 'noticiasCreate'])->name('admin.noticias.create');
Route::post('/noticias', [AdminController::class, 'noticiasStore'])->name('admin.noticias.store');
Route::get('/noticias/{id}/editar', [AdminController::class, 'noticiasEdit'])->name('admin.noticias.edit');
Route::put('/noticias/{id}', [AdminController::class, 'noticiasUpdate'])->name('admin.noticias.update');
Route::delete('/noticias/{id}', [AdminController::class, 'noticiasDestroy'])->name('admin.noticias.destroy');
// Escanear QR
Route::get('/escanear-qr', [AdminController::class, 'escanearQr'])->name('admin.escanear');
Route::post('/validar-qr', [AdminController::class, 'validarQr'])->name('admin.validar.qr');
// Carrusel Inicio
Route::get('/carousel', [\App\Http\Controllers\Admin\CarouselItemController::class, 'index'])->name('admin.carousel.index');
Route::get('/carousel/crear', [\App\Http\Controllers\Admin\CarouselItemController::class, 'create'])->name('admin.carousel.create');
Route::post('/carousel', [\App\Http\Controllers\Admin\CarouselItemController::class, 'store'])->name('admin.carousel.store');
Route::get('/carousel/{carouselItem}/editar', [\App\Http\Controllers\Admin\CarouselItemController::class, 'edit'])->name('admin.carousel.edit');
Route::put('/carousel/{carouselItem}', [\App\Http\Controllers\Admin\CarouselItemController::class, 'update'])->name('admin.carousel.update');
Route::delete('/carousel/{carouselItem}', [\App\Http\Controllers\Admin\CarouselItemController::class, 'destroy'])->name('admin.carousel.destroy');
// Sponsors
Route::get('/sponsors', [AdminController::class, 'sponsorsIndex'])->name('admin.sponsors.index');
Route::get('/sponsors/crear', [AdminController::class, 'sponsorsCreate'])->name('admin.sponsors.create');
Route::post('/sponsors', [AdminController::class, 'sponsorsStore'])->name('admin.sponsors.store');
Route::get('/sponsors/{id}/editar', [AdminController::class, 'sponsorsEdit'])->name('admin.sponsors.edit');
Route::put('/sponsors/{id}', [AdminController::class, 'sponsorsUpdate'])->name('admin.sponsors.update');
Route::delete('/sponsors/{id}', [AdminController::class, 'sponsorsDestroy'])->name('admin.sponsors.destroy');
// Configuración General
Route::get('/configuracion', [AdminController::class, 'settingsIndex'])->name('admin.settings.index');
Route::post('/configuracion', [AdminController::class, 'settingsUpdate'])->name('admin.settings.update');
Route::post('/configuracion/tarea-manual', [AdminController::class, 'runManualTask'])->name('admin.settings.manual.task');
// Torneos
Route::get('/torneos', [AdminController::class, 'torneosIndex'])->name('admin.torneos.index');
Route::get('/torneos/crear', [AdminController::class, 'torneosCreate'])->name('admin.torneos.create');
Route::post('/torneos', [AdminController::class, 'torneosStore'])->name('admin.torneos.store');
Route::get('/torneos/{id}/editar', [AdminController::class, 'torneosEdit'])->name('admin.torneos.edit');
Route::put('/torneos/{id}', [AdminController::class, 'torneosUpdate'])->name('admin.torneos.update');
Route::delete('/torneos/{id}', [AdminController::class, 'torneosDestroy'])->name('admin.torneos.destroy');
Route::post('/torneos/{id}/equipos', [AdminController::class, 'torneoAddEquipo'])->name('admin.torneos.equipos.add');
Route::delete('/torneos/{id}/equipos/{id_equipo}', [AdminController::class, 'torneoRemoveEquipo'])->name('admin.torneos.equipos.remove');
// Fixture Generator
Route::post('/torneos/{id}/generar-fixture', [\App\Http\Controllers\Admin\FixtureController::class, 'preview'])->name('admin.torneos.fixture.preview');
Route::post('/torneos/{id}/confirmar-fixture', [\App\Http\Controllers\Admin\FixtureController::class, 'confirmar'])->name('admin.torneos.fixture.confirmar');
// Importador de resultados históricos
Route::get('/torneos/{id}/importar', [\App\Http\Controllers\Admin\FixtureController::class, 'importForm'])->name('admin.torneos.importar');
Route::post('/torneos/{id}/importar', [\App\Http\Controllers\Admin\FixtureController::class, 'importStore'])->name('admin.torneos.importar.store');
// Playoffs
Route::get('/torneos/{id}/playoffs-manage', [\App\Http\Controllers\Admin\FixtureController::class, 'managePlayoffs'])->name('admin.torneos.playoffs.manage');
Route::post('/torneos/{id}/generar-playoffs', [\App\Http\Controllers\Admin\FixtureController::class, 'generarPlayoffs'])->name('admin.torneos.playoffs.generar');
Route::post('/torneos/{id}/playoffs-avanzar', [\App\Http\Controllers\Admin\FixtureController::class, 'avanzarGanador'])->name('admin.torneos.playoffs.avanzar');
});
// Pestaña de Playoffs (Público)
Route::get('/torneos/{id}/playoffs', [App\Http\Controllers\TorneoController::class, 'playoffs'])->name('torneos.playoffs');
// OnAPB Genius Agent
Route::post('/agent/chat', [\App\Http\Controllers\GeniusAgentController::class, 'chat'])
->middleware('throttle:20,1')
->name('agent.chat');