diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index 87a034926769f706a54507604e114bbe72737b09..1c4a33756c2386c64ba6b1dfa528af6e846f0cd5 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -2,8 +2,11 @@
 
 namespace App\Http\Controllers;
 
+use App\Models\User;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Validator;
+use Laravel\Sanctum\PersonalAccessToken;
 
 class AuthController extends Controller
 {
@@ -24,9 +27,12 @@ class AuthController extends Controller
         ]);
     }
 
-    public function logout()
+    public function logout(Request $request)
     {
-        auth()->user()->tokens()->delete();
-        return  response()->json(['Token revoked']);
+        $user = UserController::getUserByToken($request);
+        if(1 != $user->tokens()->delete()){
+            return "false";
+        }
+        return "true";
     }
 }
\ No newline at end of file
diff --git a/app/Models/Bike.php b/app/Models/Bike.php
index 05c406f1ad5065fdd508355e34404aa34f5746ac..75a3e695eb5876248c169e564045b74e386d032e 100644
--- a/app/Models/Bike.php
+++ b/app/Models/Bike.php
@@ -6,17 +6,25 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasMany;
+use Nanigans\SingleTableInheritance\SingleTableInheritanceTrait;
 
 /**
  * @method static create(array $array)
+ * @method static find(int $int)
+ * @property mixed $id
+ * @property mixed $bikeable_type
+ * @property mixed|null $stop_id
  */
 class Bike extends Model
 {
     use HasFactory;
 
+    protected $table = "bikes";
+
     protected $fillable = [
         'stop_id',
         'unlocked',
+        'type'
     ];
 
     public function stop(): BelongsTo{
@@ -26,4 +34,8 @@ class Bike extends Model
     public function routes(): HasMany{
         return $this->hasMany(Route::class);
     }
+
+    public function bikeable(){
+        return $this->morphTo();
+    }
 }
diff --git a/app/Models/ElectricBike.php b/app/Models/ElectricBike.php
index 8991516c9ecc90fa3e9b6aee3eec9e8241a4c42e..de5833eb74cae00762939dcfd6d5ce0b2b33995f 100644
--- a/app/Models/ElectricBike.php
+++ b/app/Models/ElectricBike.php
@@ -14,4 +14,8 @@ class ElectricBike extends Bike
         'id',
         'battery',
     ];
+
+    public function bike(){
+        return $this->morphOne(Bike::class, 'bikeable');
+    }
 }
diff --git a/app/Models/Reward.php b/app/Models/Reward.php
index 3b40b1923ef096321fe69d667b3787dc7775a995..e108eb03c19a837366e856ff345948d05d082114 100644
--- a/app/Models/Reward.php
+++ b/app/Models/Reward.php
@@ -8,6 +8,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
 /**
  * @method static create(array $array)
+ * @property mixed $redeemed
+ * @property mixed $total_available
+ * @property mixed $points
  */
 class Reward extends Model
 {
@@ -18,6 +21,10 @@ class Reward extends Model
         'description',
         'user_id',
         'reward_id',
+        'points',
+        'total_available',
+        'image',
+        'redeemed',
     ];
 
     public function users(): BelongsToMany{
diff --git a/app/Models/Route.php b/app/Models/Route.php
index 987300d4f49784fd77de0ebeaee262d4367febb0..d33714cfc6884d83495a653dc99873ae9a7dd568 100644
--- a/app/Models/Route.php
+++ b/app/Models/Route.php
@@ -6,6 +6,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
+/**
+ * @property mixed $user_id
+ * @property \Illuminate\Database\Eloquent\HigherOrderBuilderProxy|mixed $initial_stop_id
+ * @property mixed $bike_id
+ * @method static find(mixed $id)
+ */
 class Route extends Model
 {
     use HasFactory;
@@ -17,6 +23,7 @@ class Route extends Model
         "bike_id",
         "distance",
         "duration",
+        "estimated_duration",
         "points",
     ];
 
diff --git a/app/Models/Stop.php b/app/Models/Stop.php
index 2a256761eadb23783b69fb544495495482c5101b..0b74cb94dd50c52539232c92e15544ce4857c2e6 100644
--- a/app/Models/Stop.php
+++ b/app/Models/Stop.php
@@ -5,9 +5,16 @@ namespace App\Models;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\HasMany;
+use phpDocumentor\Reflection\Types\Boolean;
+use PhpParser\Node\Expr\Cast\Int_;
 
 /**
  * @method static create(array $array)
+ * @method static find($initial_stop_id)
+ * @property mixed $lng
+ * @property mixed $lat
+ * @property mixed $total_spaces
+ * @property mixed $id
  */
 class Stop extends Model
 {
@@ -34,4 +41,27 @@ class Stop extends Model
     public function routesEnd(): HasMany{
         return $this->hasMany(Route::class, "final_stop_id");
     }
+
+    public function reservations(): HasMany{
+        return $this->hasMany(Reservation::class);
+    }
+
+    public function reserved_pedal_bikes(): int{
+        return $this->reservations()->where('bike_type', '=', 'pedal')->count();
+    }
+    public function reserved_electric_bikes(): int{
+        return $this->reservations()->where('bike_type', '=', 'electric')->count();
+    }
+
+    public function check_availability_bikes(String $type): bool{
+        $available = false;
+        if ($type=="pedal" || $type=="App\Models\Bike"){
+            $bikeCount = $this->bikes()->where('bikeable_type', '=', 'App\Models\Bike')->count();
+            $available = $bikeCount > $this->reserved_pedal_bikes();
+        }else if ($type=="electric" || $type=="App\Models\ElectricBike"){
+            $bikeCount = $this->bikes()->where('bikeable_type', '=', 'App\Models\ElectricBike')->count();
+            $available = $bikeCount > $this->reserved_electric_bikes();
+        }
+        return $available;
+    }
 }
diff --git a/app/Models/User.php b/app/Models/User.php
index b9cb8bad4182d986e72afc66e46588fb667c32c9..4bb40e927eb9fc2a669c3869e7dd01f70411f5b8 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -13,6 +13,9 @@ use Laravel\Sanctum\HasApiTokens;
 /**
  * @method static create(string[] $array)
  * @method static find(int $id)
+ * @method static where(string $string, mixed $email)
+ * @property mixed $points
+ * @property mixed $id
  */
 class User extends Authenticatable
 {
@@ -55,4 +58,8 @@ class User extends Authenticatable
     public function rewards(): BelongsToMany{
         return $this->belongsToMany(Reward::class, 'user_reward')->withTimestamps();
     }
+
+    public function reservations(): HasMany{
+        return $this->hasMany(Reservation::class);
+    }
 }
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index 88da5b60052b9951ea3f8090e56d088e2f91b4ad..c29e18286d9a57da7287f04c72c800e2915db46e 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -22,8 +22,11 @@ class AppServiceProvider extends ServiceProvider
      *
      * @return void
      */
-    public function boot()
+    public function boot(\Illuminate\Http\Request $request)
     {
+        if (!empty( env('NGROK_URL') ) && $request->server->has('HTTP_X_ORIGINAL_HOST')) {
+            $this->app['url']->forceRootUrl(env('NGROK_URL'));
+        }
         JsonResource::withoutWrapping();
     }
 }
diff --git a/composer.json b/composer.json
index 0ab4cf735fc13671e559a298985978b4c2dcf0e4..e112bb19fe10252a0ccde03203a2e9dcf77183fb 100644
--- a/composer.json
+++ b/composer.json
@@ -9,7 +9,8 @@
         "guzzlehttp/guzzle": "^7.2",
         "laravel/framework": "^9.11",
         "laravel/sanctum": "^2.15",
-        "laravel/tinker": "^2.7"
+        "laravel/tinker": "^2.7",
+        "nanigans/single-table-inheritance": "~1.0"
     },
     "require-dev": {
         "fakerphp/faker": "^1.9.1",
diff --git a/composer.lock b/composer.lock
index 292c550f7374c6998d1a77fcf13efcc3b5fd0045..9ba8178b78f7ec534af1025cac4653c90b15c571 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "58fa573d0eb02b0bca9c8679dea764c0",
+    "content-hash": "a6074d6cbd7b2a35b7d18370d948483f",
     "packages": [
         {
             "name": "brick/math",
@@ -1702,6 +1702,67 @@
             ],
             "time": "2022-05-10T09:36:00+00:00"
         },
+        {
+            "name": "nanigans/single-table-inheritance",
+            "version": "v1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/jonspalmer/single-table-inheritance.git",
+                "reference": "5fd1dd86ddc5ab66bf9d1260b8de1e58ac5826ff"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/jonspalmer/single-table-inheritance/zipball/5fd1dd86ddc5ab66bf9d1260b8de1e58ac5826ff",
+                "reference": "5fd1dd86ddc5ab66bf9d1260b8de1e58ac5826ff",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/database": ">= 5.2",
+                "illuminate/support": ">= 5.2",
+                "php": ">= 7.2"
+            },
+            "require-dev": {
+                "mockery/mockery": "~1.0",
+                "orchestra/database": "3.8.*|4.*|5.*|6.*",
+                "orchestra/testbench": "3.8.*|4.*|5.*|6.*",
+                "phpunit/phpunit": "~8.0|~9.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Nanigans\\SingleTableInheritance\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jon Palmer",
+                    "email": "328224+jonspalmer@users.noreply.github.com"
+                }
+            ],
+            "description": "Single Table Inheritance Trait",
+            "keywords": [
+                "eloquent",
+                "inheritance",
+                "laravel",
+                "model",
+                "single",
+                "table"
+            ],
+            "support": {
+                "issues": "https://github.com/jonspalmer/single-table-inheritance/issues",
+                "source": "https://github.com/jonspalmer/single-table-inheritance/tree/v1.0.0"
+            },
+            "time": "2021-04-17T13:10:00+00:00"
+        },
         {
             "name": "nesbot/carbon",
             "version": "2.58.0",
diff --git a/database/migrations/2022_06_13_151027_create_bikes_table.php b/database/migrations/2022_06_13_151027_create_bikes_table.php
index 705aadf3aab4c15459a871baf8f83029d9027fd8..6e167202085fddbf2395a98a2fc6916f4ea3dea3 100644
--- a/database/migrations/2022_06_13_151027_create_bikes_table.php
+++ b/database/migrations/2022_06_13_151027_create_bikes_table.php
@@ -16,10 +16,13 @@ return new class extends Migration
         Schema::create('bikes', function (Blueprint $table) {
             $table->id();
             $table->foreignId('stop_id')
+                ->nullable()
                 ->index()
                 ->constrained()
                 ->cascadeOnUpdate();
             $table->boolean('unlocked');
+            $table->unsignedBigInteger('bikeable_id');
+            $table->string('bikeable_type');
             $table->timestamps();
         });
     }
diff --git a/database/migrations/2022_06_13_153838_create_electric_bikes_table.php b/database/migrations/2022_06_13_153838_create_electric_bikes_table.php
index db6b5b73b5caf8e379b40e3ae2d58610f49de036..0946573b306638e14a2e7c05f1818f5538c05ff1 100644
--- a/database/migrations/2022_06_13_153838_create_electric_bikes_table.php
+++ b/database/migrations/2022_06_13_153838_create_electric_bikes_table.php
@@ -17,8 +17,7 @@ return new class extends Migration
             $table->id();
             $table->integer('battery');
             $table->timestamps();
-
-            $table->foreign('id')->references('id')->on('bikes');
+            //$table->foreign('id')->references('id')->on('bikes');
         });
     }
 
diff --git a/database/migrations/2022_06_14_151011_create_routes_table.php b/database/migrations/2022_06_14_151011_create_routes_table.php
index 51d6e35c0c2649c5fa6426286baeef6404e100b9..f73d946e489367cdd01532b1e944b6d90f3dbbba 100644
--- a/database/migrations/2022_06_14_151011_create_routes_table.php
+++ b/database/migrations/2022_06_14_151011_create_routes_table.php
@@ -48,6 +48,8 @@ return new class extends Migration
                 ->nullable();
             $table->integer('duration')
                 ->nullable();
+            $table->integer('estimated_duration')
+                ->nullable();
             $table->integer('points')
                 ->nullable();
 
diff --git a/database/migrations/2022_06_15_144408_create_rewards_table.php b/database/migrations/2022_06_15_144408_create_rewards_table.php
index deebdc13d82e5969780f3d6271f280245a308ef3..485b82c633f4ad2315ba667a8f910e2f49592e1b 100644
--- a/database/migrations/2022_06_15_144408_create_rewards_table.php
+++ b/database/migrations/2022_06_15_144408_create_rewards_table.php
@@ -19,6 +19,7 @@ return new class extends Migration
             $table->string('description');
             $table->integer('points');
             $table->integer('total_available');
+            $table->integer('redeemed')->default(0);
             $table->string('image')->nullable();
             $table->timestamps();
         });
diff --git a/database/seeders/BikeSeeder.php b/database/seeders/BikeSeeder.php
index 22543e813c4b525d15a0c86a0ebe286d7772b4ad..b638f24c1af6e24f60e82ec01462073a20014f77 100644
--- a/database/seeders/BikeSeeder.php
+++ b/database/seeders/BikeSeeder.php
@@ -18,29 +18,36 @@ class BikeSeeder extends Seeder
     {
         $bike = Bike::create([
             'stop_id' => 1,
-            'unlocked' => false
+            'unlocked' => false,
+            'bikeable_id' => 1,
+            'bikeable_type' => 'App\Models\ElectricBike',
         ]);
         ElectricBike::create([
-            'id' => $bike->id,
             'battery' => 60
         ]);
         Bike::create([
             'stop_id' => 1,
-            'unlocked' => false
+            'unlocked' => false,
+            'bikeable_id' => 2,
+            'bikeable_type' => 'App\Models\Bike',
         ]);
 
         $bike = Bike::create([
             'stop_id' => 2,
-            'unlocked' => false
+            'unlocked' => false,
+            'bikeable_id' => 2,
+            'bikeable_type' => 'App\Models\ElectricBike',
         ]);
         ElectricBike::create([
-            'id' => $bike->id,
             'battery' => 70
         ]);
 
         Bike::create([
             'stop_id' => 3,
-            'unlocked' => false
+            'unlocked' => false,
+            'bikeable_id' => 4,
+            'bikeable_type' => 'App\Models\Bike',
         ]);
+
     }
 }
diff --git a/database/seeders/RewardSeeder.php b/database/seeders/RewardSeeder.php
index 54727890906059adbb61c5bb1d395b618cfb5ee2..e98dbed95f25bc9444ec8589dbb365fe14a76665 100644
--- a/database/seeders/RewardSeeder.php
+++ b/database/seeders/RewardSeeder.php
@@ -19,33 +19,38 @@ class RewardSeeder extends Seeder
             'name' => 'Reward 1',
             'description' => 'A short description',
             'points' => 100,
-            'total_available' => 5
+            'total_available' => 5,
+            "image"=> "https://images.unsplash.com/photo-1591544940847-e8c860a9464e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1974&q=80"
         ]);
         $reward->users()->sync([1,2]);
         $reward = Reward::create([
             'name' => 'Reward 2',
             'description' => 'A short description 2',
             'points' => 200,
-            'total_available' => 2
+            'total_available' => 2,
+            "image"=> "https://images.unsplash.com/photo-1621841957884-1210fe19d66d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2340&q=80"
         ]);
         $reward->users()->sync([1]);
         Reward::create([
             'name' => 'Reward 3',
             'description' => 'A short description 3',
             'points' => 1000,
-            'total_available' => 1
+            'total_available' => 1,
+            "image" => "https://images.unsplash.com/photo-1565599837634-134bc3aadce8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1335&q=80"
         ]);
         Reward::create([
             'name' => 'Reward 4',
             'description' => 'A short description 4',
             'points' => 4,
-            'total_available' => 10
+            'total_available' => 10,
+            'image' => 'https://images.unsplash.com/photo-1617257118084-339d30c49b02?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2340&q=80'
         ]);
         Reward::create([
             'name' => 'Reward 5',
             'description' => 'A short description 5',
             'points' => 500,
-            'total_available' => 5
+            'total_available' => 5,
+            "image"=> "https://images.unsplash.com/photo-1655219282218-6a4a8d91a699?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2340&q=80"
         ]);
     }
 }
diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php
index 53bc2192f850407e3505cc0871960cb70735c872..81d01bf5cbe65c87ad5464532a5b5ff92cf91205 100644
--- a/database/seeders/UserSeeder.php
+++ b/database/seeders/UserSeeder.php
@@ -18,7 +18,8 @@ class UserSeeder extends Seeder
         User::create([
             'name' => 'Jorge',
             'email' => 'jorge@uva.es',
-            'password' => '12345678'
+            'password' => bcrypt('123456'),
+            'points' => 1000
         ]);
         User::create([
             'name' => 'Mario',
diff --git a/routes/api.php b/routes/api.php
index fd621dbcf9e902b16e206e12d41295cb02eb7882..0276c009f2c0703dbd916195c7847262a4aad3d1 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -2,8 +2,12 @@
 
 use App\Http\Controllers\AuthController;
 use App\Http\Controllers\BikeController;
+use App\Http\Controllers\RewardController;
 use App\Http\Controllers\RouteController;
 use App\Http\Controllers\StopController;
+use App\Http\Resources\BikeResource;
+use App\Http\Resources\RewardColletion;
+use App\Models\Bike;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Route;
 
@@ -23,10 +27,30 @@ Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
 });
 
 Route::post('/login', [AuthController::class, 'login']);
-Route::get('/retobici/stops', [StopController::class, 'getAllStops']);
+Route::get('/stops', [StopController::class, 'getAllStops']);
+Route::get('/rewards', [RewardController::class, 'getAllRewards']);
 
 Route::middleware('auth:sanctum')->group(function (){
-    Route::post('/retobici/bikes/unlock/{bike}', [BikeController::class, 'unlockBike']);
-    Route::put('/retobici/routes', [RouteController::class, 'createRoute']);
+
+    Route::post('/stops/{bike}/unlock', [StopController::class, 'unlockBike']);
+    Route::post('/stops/{stop}/reserve/{type}', [StopController::class, 'reserveBike']);
+    Route::post('/stops/{stop}/lock', [StopController::class, 'lockBike']);
+
+    Route::put('/routes/{bike}', [RouteController::class, 'createRoute']);
+    Route::post('/routes/finish', [RouteController::class, 'finishRoute']);
+
+    Route::post('/rewards/{reward}', [RewardController::class, 'obtainReward']);
+    Route::get('/rewards/redeemed', [RewardController::class, 'getUserRewards']);
+    Route::get('/rewards/not/redeemed', [RewardController::class, 'getNotRedeemedRewards']);
+
+    Route::post('/logout', [AuthController::class, 'logout']);
+});
+
+Route::get('/test', function (){
+    $stops = \App\Models\Stop::all();
+    $remove = $stops->first();
+    return $stops->filter(function ($value) use ($remove){
+        return $value!=$remove;
+    });
 });