$userSubjects * @property-read Collection $insights * @property-read Collection $insightSchedules * @property-read Collection $telegramUsers * @property-read Collection $tokenUsages * @property-read Collection $subjects */ class User extends Authenticatable { /** @use HasFactory<\Database\Factories\UserFactory> */ use HasFactory, Notifiable, HasRoles; /** @var array */ protected $fillable = [ 'name', 'email', 'password', 'phone', 'locale', 'is_active', 'is_approved', ]; /** @var array */ protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', 'is_active' => 'boolean', 'is_approved' => 'boolean', ]; /** @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * Get the user subjects for the user. */ public function userSubjects(): HasMany { return $this->hasMany(UserSubject::class); } /** * Get the insights for the user. */ public function insights(): HasMany { return $this->hasMany(Insight::class); } /** * Get the insight schedules for the user. */ public function insightSchedules(): HasMany { return $this->hasMany(InsightSchedule::class); } /** * Get the telegram users for the user. */ public function telegramUsers(): HasMany { return $this->hasMany(TelegramUser::class); } /** * Get the token usages for the user. */ public function tokenUsages(): HasMany { return $this->hasMany(TokenUsage::class); } /** * Get the subjects created by the user. */ public function subjects(): HasMany { return $this->hasMany(Subject::class); } } PHP; writeFile($basePath . '/app/Models/User.php', $userModel); // Create controllers $controllers = [ 'app/Http/Controllers/Controller.php' => <<<'PHP' <<<'PHP' validate([ 'email' => ['required', 'string', 'email'], 'password' => ['required', 'string'], ]); if (!Auth::attempt($request->only('email', 'password'), $request->boolean('remember'))) { return back()->withErrors([ 'email' => __('auth.failed'), ])->onlyInput('email'); } $request->session()->regenerate(); return redirect()->intended(route('dashboard', absolute: false)); } /** * Destroy an authenticated session. */ public function destroy(Request $request): RedirectResponse { Auth::guard('web')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/'); } } PHP, 'app/Http/Controllers/Auth/RegisteredUserController.php' => <<<'PHP' validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class], 'password' => ['required', 'confirmed', Rules\Password::defaults()], ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), 'is_approved' => false, ]); event(new Registered($user)); Auth::login($user); return redirect(route('dashboard', absolute: false)); } } PHP, ]; foreach ($controllers as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "Controllers created.\n"; // Create routes $webRoutes = <<<'PHP' name('home'); Route::middleware('guest')->group(function () { Route::get('login', [AuthenticatedSessionController::class, 'create'])->name('login'); Route::post('login', [AuthenticatedSessionController::class, 'store']); Route::get('register', [RegisteredUserController::class, 'create'])->name('register'); Route::post('register', [RegisteredUserController::class, 'store']); }); Route::middleware('auth')->group(function () { Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])->name('logout'); Route::get('/dashboard', function () { return view('dashboard.index'); })->name('dashboard'); Route::middleware('verified')->group(function () { Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); }); }); Route::middleware(['auth', 'verified', 'role:admin|superadmin'])->prefix('admin')->name('admin.')->group(function () { Route::get('/subjects', [SubjectController::class, 'index'])->name('subjects.index'); Route::post('/subjects', [SubjectController::class, 'store'])->name('subjects.store'); Route::put('/subjects/{subject}', [SubjectController::class, 'update'])->name('subjects.update'); Route::delete('/subjects/{subject}', [SubjectController::class, 'destroy'])->name('subjects.destroy'); Route::get('/insights', [InsightController::class, 'index'])->name('insights.index'); Route::post('/insights', [InsightController::class, 'store'])->name('insights.store'); Route::get('/telegram', [TelegramController::class, 'index'])->name('telegram.index'); Route::post('/telegram/connect', [TelegramController::class, 'connect'])->name('telegram.connect'); Route::post('/telegram/disconnect', [TelegramController::class, 'disconnect'])->name('telegram.disconnect'); }); Route::middleware(['auth', 'verified', 'role:superadmin'])->prefix('superadmin')->name('superadmin.')->group(function () { Route::get('/users', [UserController::class, 'index'])->name('users.index'); Route::post('/users/{user}/approve', [UserController::class, 'approve'])->name('users.approve'); Route::post('/users/{user}/reject', [UserController::class, 'reject'])->name('users.reject'); Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy'); Route::get('/system', [SystemController::class, 'index'])->name('system.index'); Route::post('/system/subjects', [SystemController::class, 'createSubject'])->name('system.subjects.store'); Route::put('/system/subjects/{subject}', [SystemController::class, 'updateSubject'])->name('system.subjects.update'); Route::delete('/system/subjects/{subject}', [SystemController::class, 'destroySubject'])->name('system.subjects.destroy'); }); PHP; writeFile($basePath . '/routes/web.php', $webRoutes); // Create language files $langFiles = [ 'lang/en/auth.php' => <<<'PHP' 'These credentials do not match our records.', 'password' => 'The provided password is incorrect.', 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', ]; PHP, 'lang/en/dashboard.php' => <<<'PHP' 'Dashboard', 'subjects' => 'My Subjects', 'insights' => 'Insights', 'token_usage' => 'Token Usage', 'telegram' => 'Telegram', 'settings' => 'Settings', ]; PHP, 'lang/pt_BR/auth.php' => <<<'PHP' 'Estas credenciais não correspondem aos nossos registros.', 'password' => 'A senha fornecida está incorreta.', 'throttle' => 'Muitas tentativas de login. Por favor, tente novamente em :seconds segundos.', ]; PHP, 'lang/pt_BR/dashboard.php' => <<<'PHP' 'Painel de Controle', 'subjects' => 'Meus Assuntos', 'insights' => 'Insights', 'token_usage' => 'Uso de Tokens', 'telegram' => 'Telegram', 'settings' => 'Configurações', ]; PHP, 'lang/es/auth.php' => <<<'PHP' 'Estas credenciales no coinciden con nuestros registros.', 'password' => 'La contraseña proporcionada es incorrecta.', 'throttle' => 'Demasiados intentos de inicio de sesión. Por favor, inténtelo de nuevo en :seconds segundos.', ]; PHP, 'lang/es/dashboard.php' => <<<'PHP' 'Panel de Control', 'subjects' => 'Mis Temas', 'insights' => 'Ideas', 'token_usage' => 'Uso de Tokens', 'telegram' => 'Telegram', 'settings' => 'Configuración', ]; PHP, ]; foreach ($langFiles as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "Language files created.\n"; // Create seeders $databaseSeeder = <<<'PHP' 'superadmin']); $adminRole = Role::firstOrCreate(['name' => 'admin']); // Create SuperAdmin user $superAdmin = User::firstOrCreate( ['email' => 'marcocosta@gmx.com'], [ 'name' => 'Super Admin', 'password' => bcrypt('superadmin123456'), 'is_active' => true, 'is_approved' => true, ] ); $superAdmin->assignRole('superadmin'); // Create system subjects $subjects = [ ['name' => 'Aprendizado e Treinamento de Inglês', 'description' => 'Learn English language', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de Flight Simulator X', 'description' => 'Learn Flight Simulator X', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de Administração de Pequenos Negócios', 'description' => 'Learn small business administration', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de Estoicismo', 'description' => 'Learn Stoicism', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de Eletrônica', 'description' => 'Learn Electronics', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de Mandarim', 'description' => 'Learn Mandarin', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de As Leis do Triunfo', 'description' => 'Learn The Laws of Success by Napoleon Hill', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de Gurus dos Negócios', 'description' => 'Learn from business gurus: ideas, quotes, negotiation and management strategies', 'is_system' => true], ['name' => 'Aprendizado e Treinamento de Gurus dos Negócios e Riqueza', 'description' => 'Ideias, frases, modos de negociar, administrar, conquistar bem-estar financeiro, riqueza, mente milionária, arte de negociar e lei da atração.', 'is_system' => true], ]; foreach ($subjects as $subjectData) { Subject::firstOrCreate(array_merge($subjectData, ['user_id' => null])); } } } PHP; writeFile($basePath . '/database/seeders/DatabaseSeeder.php', $databaseSeeder); // Create services $openRouterService = <<<'PHP' false, 'error' => 'OpenRouter API key not configured', ]; } try { $response = Http::withHeaders([ 'Authorization' => 'Bearer ' . $apiKey, 'Content-Type' => 'application/json', 'HTTP-Referer' => config('app.url'), 'X-Title' => config('app.name'), ])->post('https://openrouter.ai/api/v1/chat/completions', [ 'model' => $model, 'messages' => [ ['role' => 'system', 'content' => "You are an expert learning assistant for the subject: {$subject}. Provide insightful, educational content."], ['role' => 'user', 'content' => $userMessage], ], 'max_tokens' => 500, ]); $data = $response->json(); if (isset($data['choices'][0]['message']['content'])) { return [ 'success' => true, 'content' => $data['choices'][0]['message']['content'], 'input_tokens' => $data['usage']['prompt_tokens'] ?? 0, 'output_tokens' => $data['usage']['completion_tokens'] ?? 0, ]; } return [ 'success' => false, 'error' => $data['error']['message'] ?? 'Unknown error', ]; } catch (\Exception $e) { Log::error('OpenRouter API error: ' . $e->getMessage()); return [ 'success' => false, 'error' => $e->getMessage(), ]; } } } PHP; writeFile($basePath . '/app/Services/OpenRouterService.php', $openRouterService); $telegramService = <<<'PHP' telegram = new Api($token); } } /** * Send a message to a Telegram user. */ public function sendMessage(string $chatId, string $message): bool { if (!$this->telegram) { $this->init(); } if (!$this->telegram) { return false; } try { $this->telegram->sendMessage([ 'chat_id' => $chatId, 'text' => $message, 'parse_mode' => 'HTML', ]); return true; } catch (\Exception $e) { Log::error('Telegram send message error: ' . $e->getMessage()); return false; } } /** * Set webhook for the bot. */ public function setWebhook(string $url): bool { if (!$this->telegram) { $this->init(); } if (!$this->telegram) { return false; } try { $this->telegram->setWebhook([ 'url' => $url, 'allowed_updates' => ['message', 'callback_query'], ]); return true; } catch (\Exception $e) { Log::error('Telegram set webhook error: ' . $e->getMessage()); return false; } } } PHP; writeFile($basePath . '/app/Services/TelegramService.php', $telegramService); // Create Insight Scheduler Command $insightScheduler = <<<'PHP' whereHas('subject', function ($q) { $q->where('is_active', true); }); if ($this->option('user')) { $query->where('user_id', $this->option('user')); } if ($this->option('subject')) { $query->where('subject_id', $this->option('subject')); } $schedules = $query->get(); $sentCount = 0; foreach ($schedules as $schedule) { if ($this->shouldSend($schedule)) { $this->sendInsight($schedule, $openRouter, $telegram); $sentCount++; } } $this->info("Sent {$sentCount} insights."); return 0; } /** * Determine if an insight should be sent based on schedule. */ private function shouldSend(InsightSchedule $schedule): bool { if (!$schedule->last_sent_at) { return true; } $lastSent = $schedule->last_sent_at; $now = now(); return match ($schedule->frequency) { 'daily' => $lastSent->lt($now->subDay()), 'weekly' => $lastSent->lt($now->subWeek()), 'biweekly' => $lastSent->lt($now->subWeeks(2)), 'monthly' => $lastSent->lt($now->subMonth()), default => true, }; } /** * Send an insight to a user. */ private function sendInsight(InsightSchedule $schedule, OpenRouterService $openRouter, TelegramService $telegram): void { $user = $schedule->user; $subject = $schedule->subject; $result = $openRouter->generateInsight( $subject->name, "Generate an insightful learning tip for {$subject->name}" ); if (!$result['success']) { $this->error("Failed to generate insight for user {$user->id}: " . $result['error']); return; } DB::transaction(function () use ($user, $subject, $result, $schedule) { // Save insight \App\Models\Insight::create([ 'user_id' => $user->id, 'subject_id' => $subject->id, 'content' => $result['content'], 'input_tokens' => $result['input_tokens'], 'output_tokens' => $result['output_tokens'], 'sent_at' => now(), ]); // Save token usage \App\Models\TokenUsage::create([ 'user_id' => $user->id, 'input_tokens' => $result['input_tokens'], 'output_tokens' => $result['output_tokens'], 'total_tokens' => $result['input_tokens'] + $result['output_tokens'], 'model' => config('services.openrouter.model'), 'provider' => 'openrouter', ]); // Update schedule $schedule->update(['last_sent_at' => now()]); // Send via Telegram if connected $telegramUser = $user->telegramUsers()->where('is_active', true)->first(); if ($telegramUser) { $telegram->sendMessage( $telegramUser->telegram_user_id, "📚 *{$subject->name}*\n\n{$result['content']}" ); } }); $this->info("Sent insight to user {$user->id} for subject {$subject->id}"); } } PHP; writeFile($basePath . '/app/Console/Commands/SendScheduledInsights.php', $insightScheduler); // Create Admin controllers $adminControllers = [ 'app/Http/Controllers/Admin/SubjectController.php' => <<<'PHP' where('is_active', true) ->get(); $userSubjects = Subject::where('user_id', $user->id) ->where('is_active', true) ->get(); $mySubjects = UserSubject::where('user_id', $user->id) ->with('subject') ->get(); return view('admin.subjects.index', compact('systemSubjects', 'userSubjects', 'mySubjects')); } /** * Store a newly created subject. */ public function store(Request $request) { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'description' => ['nullable', 'string'], 'introduction' => ['nullable', 'string'], ]); Subject::create([ 'user_id' => Auth::id(), 'name' => $request->name, 'description' => $request->description, 'introduction' => $request->introduction, 'is_system' => false, 'is_active' => true, ]); return back()->with('success', 'Subject created successfully.'); } /** * Update the specified subject. */ public function update(Request $request, Subject $subject) { $this->authorize('update', $subject); $request->validate([ 'name' => ['required', 'string', 'max:255'], 'description' => ['nullable', 'string'], 'introduction' => ['nullable', 'string'], 'is_active' => ['boolean'], ]); $subject->update($request->only('name', 'description', 'introduction', 'is_active')); return back()->with('success', 'Subject updated successfully.'); } /** * Remove the specified subject. */ public function destroy(Subject $subject) { $this->authorize('delete', $subject); $subject->delete(); return back()->with('success', 'Subject deleted successfully.'); } } PHP, 'app/Http/Controllers/Admin/InsightController.php' => <<<'PHP' id) ->with('subject') ->orderByDesc('created_at') ->paginate(20); return view('admin.insights.index', compact('insights')); } /** * Store a newly created insight. */ public function store(Request $request) { $request->validate([ 'subject_id' => ['required', 'exists:subjects,id'], 'content' => ['required', 'string'], ]); Insight::create([ 'user_id' => Auth::id(), 'subject_id' => $request->subject_id, 'content' => $request->content, 'type' => 'manual', ]); return back()->with('success', 'Insight created successfully.'); } } PHP, 'app/Http/Controllers/Admin/TelegramController.php' => <<<'PHP' telegram = $telegram; } /** * Display Telegram settings. */ public function index() { $user = Auth::user(); $telegramUser = $user->telegramUsers()->first(); return view('admin.telegram.index', compact('telegramUser')); } /** * Connect Telegram account. */ public function connect(Request $request) { $request->validate([ 'telegram_user_id' => ['required', 'string'], 'telegram_username' => ['nullable', 'string'], 'telegram_first_name' => ['nullable', 'string'], 'telegram_last_name' => ['nullable', 'string'], ]); TelegramUser::updateOrCreate( ['user_id' => Auth::id()], [ 'telegram_user_id' => $request->telegram_user_id, 'telegram_username' => $request->telegram_username, 'telegram_first_name' => $request->telegram_first_name, 'telegram_last_name' => $request->telegram_last_name, 'is_active' => true, ] ); return back()->with('success', 'Telegram connected successfully.'); } /** * Disconnect Telegram account. */ public function disconnect() { Auth::user()->telegramUsers()->delete(); return back()->with('success', 'Telegram disconnected successfully.'); } } PHP, ]; foreach ($adminControllers as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "Admin controllers created.\n"; // Create SuperAdmin controllers $superAdminControllers = [ 'app/Http/Controllers/SuperAdmin/UserController.php' => <<<'PHP' orderByDesc('created_at') ->paginate(20); return view('superadmin.users.index', compact('users')); } /** * Approve a user. */ public function approve(User $user) { $user->update(['is_approved' => true]); return back()->with('success', 'User approved successfully.'); } /** * Reject a user. */ public function reject(User $user) { $user->update(['is_approved' => false]); return back()->with('success', 'User rejected successfully.'); } /** * Remove the specified user. */ public function destroy(User $user) { $user->delete(); return back()->with('success', 'User deleted successfully.'); } } PHP, 'app/Http/Controllers/SuperAdmin/SystemController.php' => <<<'PHP' \App\Models\User::count(), 'active_users' => \App\Models\User::where('is_active', true)->count(), 'pending_users' => \App\Models\User::where('is_approved', false)->count(), 'total_subjects' => Subject::count(), 'total_insights' => \App\Models\Insight::count(), ]; return view('superadmin.system.index', compact('stats')); } /** * Create a new system subject. */ public function createSubject(Request $request) { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'description' => ['nullable', 'string'], 'introduction' => ['nullable', 'string'], ]); Subject::create([ 'user_id' => null, 'name' => $request->name, 'description' => $request->description, 'introduction' => $request->introduction, 'is_system' => true, 'is_active' => true, ]); return back()->with('success', 'System subject created successfully.'); } /** * Update the specified system subject. */ public function updateSubject(Request $request, Subject $subject) { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'description' => ['nullable', 'string'], 'introduction' => ['nullable', 'string'], 'is_active' => ['boolean'], ]); $subject->update($request->only('name', 'description', 'introduction', 'is_active')); return back()->with('success', 'System subject updated successfully.'); } /** * Remove the specified system subject. */ public function destroySubject(Subject $subject) { $subject->delete(); return back()->with('success', 'System subject deleted successfully.'); } } PHP, ]; foreach ($superAdminControllers as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "SuperAdmin controllers created.\n"; // Create views $views = [ 'resources/views/layouts/app.blade.php' => <<<'BLADE' @yield('title', config('app.name', 'Annunk')) @vite(['resources/css/app.css', 'resources/js/app.js'])
@include('layouts.navigation') @isset($header)
{{ $header }}
@endisset
@yield('content')
@stack('scripts') BLADE, 'resources/views/layouts/navigation.blade.php' => <<<'BLADE' BLADE, 'resources/views/auth/login.blade.php' => <<<'BLADE' @if (session('status'))
{{ session('status') }}
@endif
@csrf
BLADE, 'resources/views/auth/register.blade.php' => <<<'BLADE'
@csrf
BLADE, 'resources/views/dashboard/index.blade.php' => <<<'BLADE' @extends('layouts.app') @section('title', __('Dashboard')) @section('content')

{{ __('Welcome to Annunk') }}

{{ __('My Subjects') }}

{{ auth()->user()->userSubjects()->count() }}

{{ __('Total Insights') }}

{{ auth()->user()->insights()->count() }}

{{ __('Token Usage') }}

{{ number_format(auth()->user()->tokenUsages()->sum('total_tokens')) }}

{{ __('Recent Insights') }}

@forelse(auth()->user()->insights()->with('subject')->latest()->take(5)->get() as $insight)
{{ $insight->subject->name }}

{{ $insight->content }}

{{ $insight->created_at->diffForHumans() }}
@empty

{{ __('No insights yet. Start by selecting subjects!') }}

@endforelse
@endsection BLADE, ]; foreach ($views as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "Views created.\n"; // Create additional view files $adminViews = [ 'resources/views/admin/subjects/index.blade.php' => <<<'BLADE' @extends('layouts.app') @section('title', __('My Subjects')) @section('content')

{{ __('My Subjects') }}

@foreach($mySubjects as $userSubject)

{{ $userSubject->subject->name }}

{{ $userSubject->is_active ? __('Active') : __('Inactive') }}

{{ $userSubject->subject->description }}

{{ __('Every') }} {{ $userSubject->frequency_days }} {{ __('days') }}
@csrf @method('DELETE')
@endforeach
@endsection BLADE, ]; foreach ($adminViews as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "Admin views created.\n"; // Create SuperAdmin views $superAdminViews = [ 'resources/views/superadmin/users/index.blade.php' => <<<'BLADE' @extends('layouts.app') @section('title', __('User Management')) @section('content')

{{ __('User Management') }}

@foreach($users as $user) @endforeach
{{ __('Name') }} {{ __('Email') }} {{ __('Status') }} {{ __('Actions') }}
{{ $user->name }} {{ $user->email }} @if($user->is_approved) {{ __('Approved') }} @else {{ __('Pending') }} @endif @if(!$user->is_approved)
@csrf
@endif
@csrf @method('DELETE')
{{ $users->links() }}
@endsection BLADE, 'resources/views/superadmin/system/index.blade.php' => <<<'BLADE' @extends('layouts.app') @section('title', __('System Management')) @section('content')

{{ __('System Management') }}

{{ __('Total Users') }}

{{ $stats['total_users'] }}

{{ __('Active Users') }}

{{ $stats['active_users'] }}

{{ __('Pending Users') }}

{{ $stats['pending_users'] }}

{{ __('Total Insights') }}

{{ $stats['total_insights'] }}

{{ __('System Subjects') }}

@foreach(\App\Models\Subject::where('is_system', true)->get() as $subject)

{{ $subject->name }}

{{ $subject->description }}

@endforeach
@endsection BLADE, ]; foreach ($superAdminViews as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "SuperAdmin views created.\n"; // Create config/services.php additions $servicesConfig = <<<'PHP' [ 'api_key' => env('OPENROUTER_API_KEY'), 'model' => env('OPENROUTER_MODEL', 'google/gemini-2.0-flash-exp:free'), ], 'telegram' => [ 'bot_token' => env('TELEGRAM_BOT_TOKEN'), 'webhook_url' => env('TELEGRAM_WEBHOOK_URL'), ], ]; PHP; $currentServices = file_get_contents($basePath . '/config/services.php'); if (strpos($currentServices, "'openrouter'") === false) { writeFile($basePath . '/config/services.php', $currentServices . "\n" . $servicesConfig); } // Update Kernel.php to add middleware $kernelPath = $basePath . '/app/Http/Kernel.php'; if (file_exists($kernelPath)) { $kernel = file_get_contents($kernelPath); if (strpos($kernel, "'role'") === false) { $kernel = str_replace( "protected \$routeMiddleware = [\n 'auth' => \Illuminate\Auth\Middleware\Authenticate::class,", "protected \$routeMiddleware = [\n 'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,\n 'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,\n 'auth' => \Illuminate\Auth\Middleware\Authenticate::class,", $kernel ); writeFile($kernelPath, $kernel); } } // Update bootstrap/app.php for middleware aliases $bootstrapApp = file_get_contents($basePath . '/bootstrap/app.php'); if (strpos($bootstrapApp, 'Spatie\\Permission\\PermissionServiceProvider') === false) { $bootstrapApp = str_replace( "->withRouting(\n __DIR__.'/../routes/web.php',", "->withRouting(\n __DIR__.'/../routes/web.php',", $bootstrapApp ); $providersPath = $basePath . '/bootstrap/providers.php'; if (file_exists($providersPath)) { $providers = file_get_contents($providersPath); if (strpos($providers, 'Spatie\\Permission\\PermissionServiceProvider') === false) { $providers = str_replace( "return [\n //", "return [\n \\Spatie\\Permission\\PermissionServiceProvider::class,\n //", $providers ); writeFile($providersPath, $providers); } } } // Create welcome view $welcomeView = <<<'BLADE' Annunk - Learning Insights Platform @vite(['resources/css/app.css', 'resources/js/app.js'])

Learning Insights Powered by AI

Annunk delivers personalized learning insights and training content through your dashboard and Telegram bot.

BLADE; writeFile($basePath . '/resources/views/welcome.blade.php', $welcomeView); echo "All views created.\n"; // Create additional necessary files $additionalFiles = [ 'app/Policies/SubjectPolicy.php' => <<<'PHP' is_system || $subject->user_id === $user->id; } /** * Determine whether the user can create models. */ public function create(User $user): bool { return true; } /** * Determine whether the user can update the model. */ public function update(User $user, Subject $subject): bool { return $subject->user_id === $user->id || $user->hasRole('superadmin'); } /** * Determine whether the user can delete the model. */ public function delete(User $user, Subject $subject): bool { return $subject->user_id === $user->id || $user->hasRole('superadmin'); } } PHP, ]; foreach ($additionalFiles as $file => $content) { writeFile($basePath . '/' . $file, $content); } echo "Additional files created.\n"; // Update AuthServiceProvider $authServiceProvider = <<<'PHP' SubjectPolicy::class, ]; /** * Register any authentication / authorization services. */ public function boot(): void { $this->registerPolicies(); Gate::before(function ($user, $ability) { if ($user->hasRole('superadmin')) { return true; } }); } } PHP; writeFile($basePath . '/app/Providers/AuthServiceProvider.php', $authServiceProvider); echo "AuthServiceProvider created.\n"; // Create routes for API and channels $apiRoutes = <<<'PHP' json(['status' => 'ok']); }); PHP; writeFile($basePath . '/routes/api.php', $apiRoutes); $channelsRoutes = <<<'PHP' id === (int) $id; }); PHP; writeFile($basePath . '/routes/channels.php', $channelsRoutes); echo "Routes created.\n"; // Create composer.json additions if needed $composer = json_decode(file_get_contents($basePath . '/composer.json'), true); if (!isset($composer['autoload']['psr-4']['App\\Policies\\'])) { $composer['autoload']['psr-4']['App\\'] = 'app/'; file_put_contents($basePath . '/composer.json', json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); } echo "\n=== Annunk Application Structure Created Successfully ===\n"; echo "Next steps:\n"; echo "1. Run: docker exec dockerank2 bash -c 'cd /var/www/html/ank2 && composer dump-autoload'\n"; echo "2. Run: docker exec dockerank2 bash -c 'cd /var/www/html/ank2 && php artisan migrate --force'\n"; echo "3. Run: docker exec dockerank2 bash -c 'cd /var/www/html/ank2 && php artisan db:seed --force'\n"; echo "4. Access: http://localhost:16790\n"; echo "5. SuperAdmin login: marcocosta@gmx.com / superadmin123456\n";