diff --git a/app/Http/Controllers/DeviceTokenController.php b/app/Http/Controllers/DeviceTokenController.php new file mode 100644 index 0000000..a5fab81 --- /dev/null +++ b/app/Http/Controllers/DeviceTokenController.php @@ -0,0 +1,50 @@ +validated(); + + $deviceToken = DeviceToken::updateOrCreate( + ['expo_push_token' => $data['expo_push_token']], + [ + 'platform' => $data['platform'] ?? null, + 'user_id' => $request->user()->getKey(), + ], + ); + + return response()->json([ + 'message' => $deviceToken->wasRecentlyCreated + ? 'Token appareil enregistré.' + : 'Token appareil mis à jour.', + 'deviceToken' => [ + 'id' => $deviceToken->id, + 'expoPushToken' => $deviceToken->expo_push_token, + 'platform' => $deviceToken->platform, + ], + ], $deviceToken->wasRecentlyCreated ? 201 : 200); + } + + public function destroy(Request $request): Response + { + $data = $request->validate([ + 'expo_push_token' => ['required', 'string', 'max:255'], + ]); + + DeviceToken::query() + ->where('user_id', $request->user()->getKey()) + ->where('expo_push_token', $data['expo_push_token']) + ->delete(); + + return response()->noContent(); + } +} diff --git a/app/Http/Requests/DeviceTokenRequest.php b/app/Http/Requests/DeviceTokenRequest.php new file mode 100644 index 0000000..f49f57c --- /dev/null +++ b/app/Http/Requests/DeviceTokenRequest.php @@ -0,0 +1,21 @@ + ['required', 'string', 'max:255'], + 'platform' => ['nullable', 'string', 'in:ios,android,web'], + ]; + } +} diff --git a/app/Models/DeviceToken.php b/app/Models/DeviceToken.php new file mode 100644 index 0000000..60d9635 --- /dev/null +++ b/app/Models/DeviceToken.php @@ -0,0 +1,20 @@ +belongsTo(User::class); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 59d7311..241e5a1 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -7,6 +7,7 @@ use Filament\Models\Contracts\FilamentUser; use Filament\Panel; use Illuminate\Database\Eloquent\Concerns\HasUlids; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; @@ -53,6 +54,11 @@ class User extends Authenticatable implements FilamentUser } + public function deviceTokens(): HasMany + { + return $this->hasMany(DeviceToken::class); + } + public function isAdmin() { return true; diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 6fc663f..23717d0 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -19,7 +19,6 @@ return new class extends Migration $table->string('password'); $table->text('bio')->nullable(); $table->string('avatar_url', 2048)->nullable(); - $table->rememberToken(); $table->timestamps(); }); diff --git a/database/migrations/2026_05_16_122204_create_device_tokens_table.php b/database/migrations/2026_05_16_122204_create_device_tokens_table.php new file mode 100644 index 0000000..101714e --- /dev/null +++ b/database/migrations/2026_05_16_122204_create_device_tokens_table.php @@ -0,0 +1,30 @@ +id(); + $table->foreignUlid('user_id')->constrained()->cascadeOnDelete(); + $table->string('expo_push_token'); + $table->string('platform')->nullable(); + $table->timestampsTz(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('device_tokens'); + } +}; diff --git a/routes/api.php b/routes/api.php index 421d98d..e6791f4 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,6 +1,7 @@ group(function (): void { }); +Route::middleware('auth:sanctum')->group(function (): void { + Route::post('device-tokens', [DeviceTokenController::class, 'store']); + Route::delete('device-tokens', [DeviceTokenController::class, 'destroy']); +}); + Route::middleware('auth:sanctum')->apiResource('meal-posts', MealPostController::class);