AI Review Center
Commit Review Workspace ?
Select a commit on the left to inspect quality, security, business value, findings, and suggested code changes.
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']);