$plain, 'hash' => $hash, 'check' => Hash::check($plain, $hash), // should be true ]; }); Route::get('package-names/{name}/products', [ProductController::class, 'index']); Route::prefix('auth')->controller(UserController::class)->group(function () { Route::post('login-with-approo-v2', [UserController::class, 'loginV2']); Route::middleware(['throttle:3,1'])->post('login-otp', 'loginOTP'); Route::post('check-otp', 'checkOTP'); Route::post('verify-email-code','verifyEmailCode'); Route::post('login', 'login'); Route::post('register', 'register'); Route::post('resend-email-verification', [UserController::class, 'resendEmailVerification']); Route::post('/login-google', 'googleLogin'); Route::get('/oauth/callback', 'oauthCallback'); Route::middleware('auth:sanctum')->group(function () { Route::put('logout', 'logout'); }); }); Route::middleware('auth:sanctum')->group(function () { Route::apiResource('reminders', ReminderController::class); Route::get('status', [UserController::class, 'status']); Route::prefix('package-names')->controller(PackageNameController::class)->group(function () { Route::get('/', 'index'); Route::middleware('abilities:admin')->post('/', 'store'); Route::middleware('abilities:admin')->post('/{name}', 'update'); Route::put('/{name}/try', [UserController::class, 'try']); Route::middleware('abilities:admin')->post('/{name}/products', [ProductController::class, 'store']); Route::middleware('abilities:admin')->patch('/{name}/products/{id}', [ProductController::class, 'update']); Route::middleware('abilities:admin')->delete('/{name}/products/{id}', [ProductController::class, 'delete']); Route::put('/{name}/products/{id}/subscribe', [ProductController::class, 'subscribe']); }); // --------- user profile Route::post('/profile', [UserController::class, 'updateProfile']); Route::get('/profile', [UserController::class, 'profile']); ////-- leader board Route::get('/leader-board', [UserController::class, 'leaderBoard']); ////-- referral (دعوت دوستان) Route::get('/referral', [UserController::class, 'referral']); ///-- mood routes Route::post('/moods/today', [MoodController::class, 'storeUserMood']); Route::get('/moods/history', [MoodController::class, 'getUserMoods']); // --------- get moods Route::get('/moods', [MoodController::class, 'getAllMoods']); // Route::post('breathing-exercises', [BreathingExerciseController::class, 'store']); // Route::get('profile', [BreathingExerciseController::class, 'profile']); // ------------------------------------------------ Route::post('breathing-templates', [BreathingExerciseController::class, 'createTemplate']); Route::get('breathing-templates', [BreathingExerciseController::class, 'getTemplates']); Route::post('breathing-complete', [BreathingExerciseController::class, 'completeSession']); // Route::get('profile', [BreathingExerciseController::class, 'profile']); Route::put('breathing-templates/{id}', [BreathingExerciseController::class, 'updateTemplate']); Route::delete('breathing-templates/{id}', [BreathingExerciseController::class, 'deleteTemplate']); Route::get('user-templates', [BreathingExerciseController::class, 'getUserTemplates']); Route::get('breathing-sessions', [BreathingExerciseController::class, 'getSessions']); // Breathing color palette (app reads it to pick a template color; admin manages it). Route::apiResource('breathing-colors', BreathingColorController::class); /// worry box feature Route::prefix('worries')->controller(WorryController::class)->group(function () { Route::post('/', 'store'); // Create worry + note Route::get('/', 'index'); // Get all worries Route::put('/{id}', 'update'); // Edit worry & note Route::patch('/{id}/toggle', 'toggleSolved'); // Mark solved / unsolved Route::delete('/{id}', 'destroy'); // Delete worry }); /// questions feature Route::get('/questions', [QuestionController::class, 'index']); Route::post('/questions', [QuestionController::class, 'store']); Route::get('/questions/{question}', [QuestionController::class, 'show']); Route::put('/questions/{question}', [QuestionController::class, 'update']); Route::delete('/questions/{question}', [QuestionController::class, 'destroy']); /// advisor chat — suggested topics (موضوعات پیشنهادی) Route::apiResource('chat-topics', ChatTopicController::class); /// FAQ (سوالات متداول) — app reads grouped /faqs; admin manages categories & items Route::get('/faqs', [FaqController::class, 'index']); // app: categories + their questions Route::apiResource('faq-categories', FaqCategoryController::class); Route::post('/faqs', [FaqController::class, 'store']); Route::get('/faqs/{id}', [FaqController::class, 'show']); Route::put('/faqs/{id}', [FaqController::class, 'update']); Route::delete('/faqs/{id}', [FaqController::class, 'destroy']); /// app feedback — ideas & reviews (نظرات و ایده‌ها) Route::get('/app-feedback', [AppFeedbackController::class, 'mine']); Route::post('/app-feedback', [AppFeedbackController::class, 'store']); Route::middleware('abilities:admin')->group(function () { Route::get('/admin/app-feedback', [AppFeedbackController::class, 'adminIndex']); Route::delete('/admin/app-feedback/{id}', [AppFeedbackController::class, 'adminDestroy']); }); /// survey questions feature (question + description + single/multi options, answered by users) // Admin: see all users' answers (must be registered before the resource so it isn't caught by {survey_question}). Route::middleware('abilities:admin')->group(function () { // Aggregated analytics — register before the {id} routes so "analytics" isn't read as an id. Route::get('/admin/survey-questions/analytics', [SurveyQuestionController::class, 'adminAnalytics']); Route::get('/admin/survey-questions/{id}/analytics', [SurveyQuestionController::class, 'adminAnalytics']); Route::get('/admin/survey-questions', [SurveyQuestionController::class, 'adminIndex']); Route::get('/admin/survey-questions/{id}', [SurveyQuestionController::class, 'adminShow']); // User list + detail for survey admin Route::get('/admin/survey-users', [SurveyQuestionController::class, 'adminUsers']); Route::get('/admin/survey-users/{id}', [SurveyQuestionController::class, 'adminUserShow']); Route::patch('/admin/survey-users/{id}', [SurveyQuestionController::class, 'adminUserUpdate']); }); // User: answer + read questions with their own answers only. Route::get('/survey-questions/suggested-media', [SurveyQuestionController::class, 'suggestedMedia']); Route::post('/survey-questions/answers', [SurveyQuestionController::class, 'bulkAnswer']); Route::post('/survey-questions/{id}/answer', [SurveyQuestionController::class, 'answer']); Route::apiResource('survey-questions', SurveyQuestionController::class); /// slider feature // Route::get('/slider', [SliderController::class, 'index']); /// images Route::post('/images', [ImageController::class, 'store']); Route::get('/images/private', [ImageController::class, 'userImages']); Route::get('/images/all', [ImageController::class, 'allImages']); Route::get('/images/public', [ImageController::class, 'publicImages']); Route::put('/images/{id}', [ImageController::class, 'update']); // ✅ update Route::delete('/images/{id}', [ImageController::class, 'destroy']); // ✅ delete /// music // Route::post('/music', [MusicController::class, 'store']); // Route::get('/music/all', [MusicController::class, 'all']); // Route::put('/music/{id}', [MusicController::class, 'update']); // Route::delete('/music/{id}', [MusicController::class, 'destroy']); Route::get('/slider', [SliderController::class, 'index']); // list all sliders Route::post('/slider', [SliderController::class, 'store']); // create slider Route::get('/slider/{id}', [SliderController::class, 'show']); // get single slider Route::put('/slider/{id}', [SliderController::class, 'update']); // update slider (json) Route::post('/slider/{id}', [SliderController::class, 'update']); // update slider (multipart: image upload) Route::delete('/slider/{id}', [SliderController::class, 'destroy']); // delete slider /// announcements Route::get('/announcements/latest', [AnnouncementController::class, 'latest']); // single latest active (app) Route::get('/announcements', [AnnouncementController::class, 'index']); // list all (admin) Route::post('/announcements', [AnnouncementController::class, 'store']); // create Route::get('/announcements/{id}', [AnnouncementController::class, 'show']); // single Route::put('/announcements/{id}', [AnnouncementController::class, 'update']); // update (json) Route::post('/announcements/{id}', [AnnouncementController::class, 'update']); // update (multipart: image) Route::delete('/announcements/{id}', [AnnouncementController::class, 'destroy']); // delete /// app versions Route::get('/versions/latest', [AppVersionController::class, 'latest']); // newest version (app update check) Route::get('/versions', [AppVersionController::class, 'index']); // list all (admin) Route::post('/versions', [AppVersionController::class, 'store']); // create Route::get('/versions/{id}', [AppVersionController::class, 'show']); // single Route::put('/versions/{id}', [AppVersionController::class, 'update']); // update (json) Route::post('/versions/{id}', [AppVersionController::class, 'update']); // update (multipart: image) Route::delete('/versions/{id}', [AppVersionController::class, 'destroy']); // delete /// themes (color themes a scene can use) Route::get('/themes', [ThemeController::class, 'index']); Route::get('/themes/{id}', [ThemeController::class, 'show']); Route::put('/themes/{id}', [ThemeController::class, 'update']); // edit name / colors / order / active Route::post('/themes/{id}', [ThemeController::class, 'update']); // same, for method-spoofed clients /// scenes (تنظیمات صحنه) — each scene has an image, optional video, and sound // Consolidated settings screen (all scenes + current user's preferences) in one call. Route::get('/scene-settings', [SceneController::class, 'settings']); Route::put('/scene-settings', [SceneController::class, 'updateSettings']); Route::get('/scenes', [SceneController::class, 'index']); Route::post('/scenes', [SceneController::class, 'store']); // multipart: image, video, sound Route::get('/scenes/{id}', [SceneController::class, 'show']); Route::post('/scenes/{id}', [SceneController::class, 'update']); // multipart update Route::delete('/scenes/{id}', [SceneController::class, 'destroy']); /// insight timer (زمان‌سنج) // Builder catalogs (bells / background sounds / background images) in one call. Route::get('/timer/options', [TimerPresetController::class, 'options']); // Saved timers per user (ذخیره‌شده‌های من). Route::get('/timer-presets', [TimerPresetController::class, 'index']); Route::post('/timer-presets', [TimerPresetController::class, 'store']); Route::get('/timer-presets/{id}', [TimerPresetController::class, 'show']); Route::put('/timer-presets/{id}', [TimerPresetController::class, 'update']); Route::delete('/timer-presets/{id}', [TimerPresetController::class, 'destroy']); // Timer sound/image catalogs (POST update for multipart uploads). Route::get('/bell-sounds', [BellSoundController::class, 'index']); Route::post('/bell-sounds', [BellSoundController::class, 'store']); Route::get('/bell-sounds/{id}', [BellSoundController::class, 'show']); Route::post('/bell-sounds/{id}', [BellSoundController::class, 'update']); Route::delete('/bell-sounds/{id}', [BellSoundController::class, 'destroy']); Route::get('/background-sounds', [BackgroundSoundController::class, 'index']); Route::post('/background-sounds', [BackgroundSoundController::class, 'store']); Route::get('/background-sounds/{id}', [BackgroundSoundController::class, 'show']); Route::post('/background-sounds/{id}', [BackgroundSoundController::class, 'update']); Route::delete('/background-sounds/{id}', [BackgroundSoundController::class, 'destroy']); // Background images for timers reuse the shared images catalog (see /images routes). ///media Route::get('/media/filters', [MediaController::class, 'filters']); Route::get('/media/search', [MediaController::class, 'search']); Route::get('/media/popular', [MediaController::class, 'popular']); Route::get('/media/newest', [MediaController::class, 'newest']); Route::get('/media/recently-played', [MediaController::class, 'recentlyPlayed']); Route::post('/media', [MediaController::class, 'store']); Route::get('/media', [MediaController::class, 'index']); Route::post('/media/{id}', [MediaController::class, 'update']); Route::get('/media/saved', [MediaController::class, 'saved']); Route::delete('/media/{id}', [MediaController::class, 'destroy']); Route::get('/media/{id}', [MediaController::class, 'show']); Route::post('/media/{id}/play', [MediaController::class, 'recordPlay']); Route::post('/media/{id}/save', [MediaController::class, 'toggleSaveMedia']); Route::post('/media/{id}/rate', [MediaController::class, 'rate']); Route::post('/media/{id}/comment', [MediaController::class, 'storeComment']); Route::get('/media/{id}/comments', [MediaController::class, 'getComments']); Route::post('/media/{id}/feedback', [MediaController::class, 'submitFeedback']); //add note to media Route::post('/media/{id}/note', [MediaController::class, 'storeNote']); // Media categories // Category with its sub-categories, each carrying its medias. Route::get('categories/{id}/grouped', [CategoryController::class, 'grouped']); // Explicit POST update so an icon image can be uploaded (multipart can't ride a PUT). Route::post('categories/{id}', [CategoryController::class, 'update']); Route::apiResource('categories', CategoryController::class); // Media sub categories Route::get('sub-categories/by-category/{categoryId}', [SubCategoryController::class, 'index']); Route::apiResource('sub-categories', SubCategoryController::class); // Music Categories // Category with its sub-categories, each carrying its playlists. Route::get('music-categories/{id}/grouped', [MusicCategoryController::class, 'grouped']); // Explicit POST update so an image can be uploaded (multipart can't ride a PUT). Route::post('music-categories/{id}', [MusicCategoryController::class, 'update']); Route::apiResource('music-categories', MusicCategoryController::class); Route::get('public/music-categories', [MusicCategoryController::class, 'index']); // Music Playlists // Explicit POST update so a playlist image can be uploaded (multipart can't ride a PUT). Route::post('music-playlists/{music_playlist}', [MusicPlaylistController::class, 'update']); Route::apiResource('music-playlists', MusicPlaylistController::class); Route::get('playlists/by-category/{categoryId}', [MusicPlaylistController::class, 'index']); // Subcategory routes Route::apiResource('music-subcategories', MusicSubcategoryController::class); Route::get('subcategories/by-category/{categoryId}', [MusicSubcategoryController::class, 'index']); // Music Routes - Add this line before your other routes Route::get('music/all', [MusicController::class, 'getAllMusic']); // For old app compatibility // Music Route::get('music/playlist/{playlistId}', [MusicController::class, 'getMusicByPlaylist']); Route::post('music/{musicId}/add-to-playlist', [MusicController::class, 'addToPlaylist']); Route::delete('music/{musicId}/remove-from-playlist', [MusicController::class, 'removeFromPlaylist']); Route::post('music/update-order', [MusicController::class, 'updateOrder']); Route::apiResource('music', MusicController::class); // Generic Rating Routes (works for both music and media) Route::prefix('ratings')->group(function () { Route::post('{type}/{id}', [RatingController::class, 'rate']); Route::get('{type}/{id}/user', [RatingController::class, 'getUserRating']); Route::delete('{type}/{id}', [RatingController::class, 'deleteRating']); Route::get('{type}/{id}', [RatingController::class, 'getRatings']); Route::get('top/{type}', [RatingController::class, 'topRated']); }); // Generic Comment Routes (works for both music and media) Route::prefix('comments')->group(function () { Route::post('{type}/{id}', [CommentController::class, 'addComment']); Route::get('{type}/{id}', [CommentController::class, 'getComments']); Route::put('{type}/{id}/{commentId}', [CommentController::class, 'updateComment']); Route::delete('{type}/{id}/{commentId}', [CommentController::class, 'deleteComment']); Route::get('most/{type}', [CommentController::class, 'mostCommented']); }); // Save routes (works for all models) Route::prefix('saves')->group(function () { Route::post('/save', [SaveController::class, 'save']); Route::post('/unsave', [SaveController::class, 'unsave']); Route::post('/toggle', [SaveController::class, 'toggleSave']); Route::get('/my-saved', [SaveController::class, 'mySavedItems']); Route::post('/check', [SaveController::class, 'checkSaved']); }); // Combined comment + like in one request (music / media / playlist) Route::post('interactions/{type}/{id}', [InteractionController::class, 'store']); // Like routes (only for music and media) Route::prefix('likes')->group(function () { Route::post('/like', [LikeController::class, 'like']); Route::post('/unlike', [LikeController::class, 'unlike']); Route::post('/toggle', [LikeController::class, 'toggleLike']); Route::get('/my-liked', [LikeController::class, 'myLikedItems']); Route::post('/check', [LikeController::class, 'checkLiked']); Route::get('/top-liked', [LikeController::class, 'topLiked']); }); });