Showing AI reviews for safee-meet-backend
Project AI Score ?
72%
Quality Avg ?
76%
Security Avg ?
67%
Reviews ?
16

Review Result ?

jattin01/safee-meet-backend · ecbcc260
This commit adds a meeting approval workflow and push notification support including updates to models, controllers, services, and database migrations. The implementation uses appropriate validation, authorization, and error handling frameworks. It also silently handles push notification errors, avoiding impact on main API flows.
Quality ?
85%
Security ?
80%
Business Value ?
90%
Maintainability ?
83%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Add Checks Or Logging For State Transition...
Where app/Http/Controllers/Api/MeetingController.php:159-197
Issue / Evidence Add checks or logging for state transitions and possible edge cases during approval/denial to improve bug risk and observability
Suggested Fix Review and simplify this section.
Security Issue
Where app/Http/Controllers/Api/MeetingController.php:290-296
Issue / Evidence Enhance error messages or create dedicated exception classes for better security and debugging clarity
Suggested Fix Review and simplify this section.
Consider More Granular Logging Or Retry Me...
Where app/Services/PushNotificationService.php:34-40
Issue / Evidence Consider more granular logging or retry mechanisms on failed push messages to enhance reliability and business value
Suggested Fix Review and simplify this section.
Missing Validation
Where app/Http/Controllers/Api/DeviceController.php:17-19
Issue / Evidence Enhance validation to check token format or length to improve robustness and reduce potential bugs
Suggested Fix Review and simplify this section.
Missing Validation
Where app/Services/PushNotificationService.php:23-25
Issue / Evidence Add a mechanism to unregister or invalidate stale FCM tokens to improve quality and security
Suggested Fix Review and simplify this section.
Add A Down() Implementation Or Warning Com...
Where database/migrations/2026_07_26_120000_add_pending_approval_and_declined_to_meetings_status.php:20
Issue / Evidence Add a down() implementation or warning comment to avoid ambiguous rollback behavior and improve maintainability
Suggested Fix Review and simplify this section.
Add Down() Method To Safely Drop Fcm Token...
Where database/migrations/2026_07_26_120001_add_fcm_token_to_users_table.php:19-24
Issue / Evidence Add down() method to safely drop FCM token columns during rollback, enhancing migration reliability
Suggested Fix Review and simplify this section.
Code Change Preview · app/Http/Controllers/Api/DeviceController.php ?
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Http\Controllers\Api;
+ 
+ use App\Http\Controllers\Controller;
+ use Illuminate\Http\JsonResponse;
+ use Illuminate\Http\Request;
+ 
+ class DeviceController extends Controller
+ {
+     /**
+      * POST /api/device/fcm-token — registers/refreshes the authenticated
+      * user's push notification token. Single token per user (last write wins).
+      */
+     public function syncFcmToken(Request $request): JsonResponse
+     {
+         $validated = $request->validate([
+             'fcm_token' => ['required', 'string'],
Removed / Before Commit
- use App\Http\Controllers\Controller;
- use App\Models\Meeting;
- use App\Models\User;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\Request;
- use Illuminate\Validation\Rule;
- use Illuminate\Validation\ValidationException;
- 
- class MeetingController extends Controller
- {
- /**
- * GET /api/meetings — Recent Meetings list (Home screen + "See all")
- */
- 'purpose' => $validated['purpose'] ?? null,
- 'item_or_service' => $validated['item_or_service'] ?? null,
- 'type' => $validated['type'] ?? 'other',
-             'status' => 'scheduled',
- 'trust_score_snapshot' => $request->user()->trust_score,
Added / After Commit
+ use App\Http\Controllers\Controller;
+ use App\Models\Meeting;
+ use App\Models\User;
+ use App\Services\PushNotificationService;
+ use Illuminate\Http\JsonResponse;
+ use Illuminate\Http\Request;
+ use Illuminate\Validation\Rule;
+ use Illuminate\Validation\ValidationException;
+ 
+ class MeetingController extends Controller
+ {
+     public function __construct(private readonly PushNotificationService $push)
+     {
+     }
+ 
+ /**
+ * GET /api/meetings — Recent Meetings list (Home screen + "See all")
+ */
Removed / Before Commit
- 'last_seen_at',
- 'suspended_reason',
- 'deleted_reason',
- ];
- 
- protected $hidden = [
Added / After Commit
+ 'last_seen_at',
+ 'suspended_reason',
+ 'deleted_reason',
+         'fcm_token',
+         'fcm_token_updated_at',
+ ];
+ 
+ protected $hidden = [
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ namespace App\Services;
+ 
+ use App\Models\User;
+ use Illuminate\Support\Facades\Log;
+ use Kreait\Firebase\Messaging\CloudMessage;
+ use Kreait\Firebase\Messaging\Notification;
+ use Kreait\Laravel\Firebase\Facades\Firebase;
+ use Throwable;
+ 
+ class PushNotificationService
+ {
+     /**
+      * Sends a push notification to a user's registered device. No-ops
+      * silently if the user has no FCM token; never throws — a notification
+      * failure must never break the endpoint that triggered it.
+      *
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Support\Facades\DB;
+ 
+ return new class extends Migration
+ {
+     /**
+      * Adds the guest-approval flow's two new statuses. Additive only —
+      * existing rows keep whatever status they already have.
+      */
+     public function up(): void
+     {
+         DB::statement("ALTER TABLE meetings MODIFY status ENUM('draft','scheduled','active','completed','cancelled','expired','emergency','live','incident_reported','pending_approval','declined') NOT NULL DEFAULT 'scheduled'");
+     }
+ 
+     public function down(): void
+     {
Removed / Before Commit

                                                
Added / After Commit
+ <?php
+ 
+ use Illuminate\Database\Migrations\Migration;
+ use Illuminate\Database\Schema\Blueprint;
+ use Illuminate\Support\Facades\Schema;
+ 
+ return new class extends Migration
+ {
+     public function up(): void
+     {
+         Schema::table('users', function (Blueprint $table): void {
+             if (!Schema::hasColumn('users', 'fcm_token')) {
+                 $table->string('fcm_token')->nullable();
+             }
+             if (!Schema::hasColumn('users', 'fcm_token_updated_at')) {
+                 $table->timestamp('fcm_token_updated_at')->nullable();
+             }
+         });
Removed / Before Commit
- 
- use App\Http\Controllers\Auth\AuthController;
- use App\Http\Controllers\Api\AuthController as PhoneOtpAuthController;
- use App\Http\Controllers\Api\EmergencyContactController;
- use App\Http\Controllers\Api\MeetingController;
- use App\Http\Controllers\Api\ReportController;
- 
- Route::apiResource('meetings', MeetingController::class)->only(['index', 'store', 'show', 'destroy']);
- Route::post('meetings/{meeting}/accept', [MeetingController::class, 'accept']);
- Route::post('meetings/{meeting}/reschedule', [MeetingController::class, 'reschedule']);
- Route::post('meetings/{meeting}/cancel', [MeetingController::class, 'cancel']);
- Route::post('meetings/{meeting}/arrive', [MeetingController::class, 'arrive']);
- Route::post('meetings/{meeting}/location', [MeetingController::class, 'pingLocation']);
- Route::post('meetings/{meeting}/complete', [MeetingController::class, 'complete']);
- Route::post('meetings/{meeting}/review', [ReviewController::class, 'store']);
- 
- Route::get('reviews', [ReviewController::class, 'index']);
- Route::post('reviews/{review}/helpful', [ReviewController::class, 'markHelpful']);
Added / After Commit
+ 
+ use App\Http\Controllers\Auth\AuthController;
+ use App\Http\Controllers\Api\AuthController as PhoneOtpAuthController;
+ use App\Http\Controllers\Api\DeviceController;
+ use App\Http\Controllers\Api\EmergencyContactController;
+ use App\Http\Controllers\Api\MeetingController;
+ use App\Http\Controllers\Api\ReportController;
+ 
+ Route::apiResource('meetings', MeetingController::class)->only(['index', 'store', 'show', 'destroy']);
+ Route::post('meetings/{meeting}/accept', [MeetingController::class, 'accept']);
+         Route::post('meetings/{meeting}/approve', [MeetingController::class, 'approve']);
+         Route::post('meetings/{meeting}/deny', [MeetingController::class, 'deny']);
+ Route::post('meetings/{meeting}/reschedule', [MeetingController::class, 'reschedule']);
+ Route::post('meetings/{meeting}/cancel', [MeetingController::class, 'cancel']);
+ Route::post('meetings/{meeting}/arrive', [MeetingController::class, 'arrive']);
+ Route::post('meetings/{meeting}/location', [MeetingController::class, 'pingLocation']);
+ Route::post('meetings/{meeting}/complete', [MeetingController::class, 'complete']);
+ Route::post('meetings/{meeting}/review', [ReviewController::class, 'store']);