diff --git a/.gitignore b/.gitignore
index d272472a60ed42d464084017fd58f4a764860e9e..9d69baa07a9349a0ed0d73d664ad697aa5e65a9f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,10 @@
 ### Own ###
 taller
 *.pdf
-**/target/
\ No newline at end of file
+**/target/
+**/.vscode
+**/tmp
+**/*.tmp
+*.ln
+*.log
+
diff --git a/angular/RestClient/angular.json b/angular/RestClient/angular.json
index 2fe5dbb241e8371e452ea965dee70c7249575f0c..32760665f49d122760236268ce4124bfaa0b6bde 100644
--- a/angular/RestClient/angular.json
+++ b/angular/RestClient/angular.json
@@ -32,12 +32,7 @@
             "scripts": [
               "node_modules/jquery/dist/jquery.min.js",
               "node_modules/bootstrap/dist/js/bootstrap.min.js"
-            ],
-            "server": "src/main.server.ts",
-            "prerender": true,
-            "ssr": {
-              "entry": "server.ts"
-            }
+            ]
           },
           "configurations": {
             "production": {
diff --git a/angular/RestClient/environments/environment.prod.ts b/angular/RestClient/environments/environment.prod.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e7abc07ec43af506db487532b2175c50676f3534
--- /dev/null
+++ b/angular/RestClient/environments/environment.prod.ts
@@ -0,0 +1,9 @@
+const monolithUrl = 'http://room-booking:8080';
+
+export const environment = {
+  production: true,
+  authAPI: 'http://auth-api:8101',
+  userAPI: `http://${monolithUrl}`,
+  hotelAPI: `http://${monolithUrl}`,
+  bookingAPI: `http://${monolithUrl}`,
+};
diff --git a/angular/RestClient/environments/environment.ts b/angular/RestClient/environments/environment.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d82bc7fa8278b4fb12dd2db673f4b2c116cf8e3b
--- /dev/null
+++ b/angular/RestClient/environments/environment.ts
@@ -0,0 +1,9 @@
+const monolithUrl = 'localhost:8080';
+
+export const environment = {
+  production: true,
+  authAPI: 'http://localhost:8101',
+  userAPI: `http://${monolithUrl}/users`,
+  hotelAPI: `http://${monolithUrl}/hotels`,
+  bookingAPI: `http://${monolithUrl}/bookings`,
+};
diff --git a/angular/RestClient/package-lock.json b/angular/RestClient/package-lock.json
index a5d201bf11869266cc967b0e328660d5d8870bc7..af241069cc8acddc06a48c70b6d1dd25125a07ac 100644
--- a/angular/RestClient/package-lock.json
+++ b/angular/RestClient/package-lock.json
@@ -25,6 +25,7 @@
         "bootstrap": "^3.4.0",
         "express": "^4.18.2",
         "jquery": "^3.4.1",
+        "jwt-decode": "^4.0.0",
         "rxjs": "~7.8.0",
         "tslib": "^2.3.0",
         "zone.js": "~0.14.10"
@@ -5468,9 +5469,9 @@
       "license": "ISC"
     },
     "node_modules/bootstrap": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.0.tgz",
-      "integrity": "sha512-F1yTDO9OHKH0xjl03DsOe8Nu1OWBIeAugGMhy3UTIYDdbbIPesQIhCEbj+HEr6wqlwweGAlP8F3OBC6kEuhFuw==",
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz",
+      "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==",
       "license": "MIT",
       "engines": {
         "node": ">=6"
@@ -6329,9 +6330,9 @@
       }
     },
     "node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "version": "7.0.6",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -8555,9 +8556,9 @@
       }
     },
     "node_modules/jquery": {
-      "version": "3.4.1",
-      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
-      "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==",
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
+      "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
       "license": "MIT"
     },
     "node_modules/js-tokens": {
@@ -8654,6 +8655,15 @@
       ],
       "license": "MIT"
     },
+    "node_modules/jwt-decode": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
+      "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/karma": {
       "version": "6.4.4",
       "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz",
diff --git a/angular/RestClient/package.json b/angular/RestClient/package.json
index 262eacd1144f0eaab113dda4aad24eedab9ff958..a17778b07370cfdb71c9dcc5f6137b413ab929cf 100644
--- a/angular/RestClient/package.json
+++ b/angular/RestClient/package.json
@@ -28,6 +28,7 @@
     "bootstrap": "^3.4.0",
     "express": "^4.18.2",
     "jquery": "^3.4.1",
+    "jwt-decode": "^4.0.0",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",
     "zone.js": "~0.14.10"
diff --git a/angular/RestClient/src/app/app.config.ts b/angular/RestClient/src/app/app.config.ts
index 1f668ea1741efbdb605f6d418a9a93f53f1327fa..a7435caa914532ca9a3c5f085f6b02b3f36aa603 100644
--- a/angular/RestClient/src/app/app.config.ts
+++ b/angular/RestClient/src/app/app.config.ts
@@ -1,19 +1,22 @@
 import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
 import { provideRouter } from '@angular/router';
 import { routes } from './app.routes';
-import { provideHttpClient, withFetch } from '@angular/common/http';
+import {
+  provideHttpClient,
+  withFetch,
+  withInterceptors,
+} from '@angular/common/http';
 import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
 import { ReactiveFormsModule } from '@angular/forms'; // Added import for ReactiveFormsModule
 import { provideNativeDateAdapter } from '@angular/material/core';
-import { provideClientHydration } from '@angular/platform-browser';
+import { authRequest } from './auth/auth.interceptor';
 
 export const appConfig: ApplicationConfig = {
   providers: [
     provideNativeDateAdapter(),
     provideZoneChangeDetection({ eventCoalescing: true }),
     provideRouter(routes),
-    provideClientHydration(),
-    provideHttpClient(withFetch()),
+    provideHttpClient(withFetch(), withInterceptors([authRequest])),
     provideAnimationsAsync(),
     ReactiveFormsModule,
   ],
diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index 435147aaba7cab6a92b72a93c0bf217eded0540d..13e66397bddf5dafcd427e12591f6b682ab1f4d2 100644
--- a/angular/RestClient/src/app/app.routes.ts
+++ b/angular/RestClient/src/app/app.routes.ts
@@ -5,6 +5,7 @@ import { HotelRegisterComponent } from './core/features/hotel/hotel-register/hot
 import { MainPageComponent } from './core/features/user/main-page/main-page.component';
 import { BookingListComponent } from './core/features/bookings/booking-list/booking-list.component';
 import { UserBookingListComponent } from './core/features/user/user-booking-list/user-booking-list.component';
+import { UserFormComponent } from './core/features/user/user-form/user-form.component';
 
 import { LoginComponent } from './core/features/auth/login/login.component';
 import { UserFormComponent } from './core/features/user/user-form/user-form.component';
@@ -49,9 +50,6 @@ export const routes: Routes = [
   {
     path: 'me/hotels/:id',
   },
-  {
-    path: 'auth/login',
-  },
   {
     path: 'me/hotels/:id/bookings',
   },
diff --git a/angular/RestClient/src/app/auth/auth.interceptor.ts b/angular/RestClient/src/app/auth/auth.interceptor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..63a139b74505e95db8b5c3c88f508696e7ff73be
--- /dev/null
+++ b/angular/RestClient/src/app/auth/auth.interceptor.ts
@@ -0,0 +1,32 @@
+import { HttpInterceptorFn } from '@angular/common/http';
+import { inject } from '@angular/core';
+import { LocalStorageService } from '../shared/local-storage.service';
+
+const excluded = ['/login', '/register'];
+
+function isExcludedUrl(url: string) {
+  return excluded.some((excluded) => url.includes(excluded));
+}
+
+export const authRequest: HttpInterceptorFn = (req, next) => {
+  // Obtener el token desde localStorage (o cualquier otro mecanismo)
+  const storage = inject(LocalStorageService); // Obtener instancia del servicio
+  const token = storage.read<{ token: string }>('token');
+
+  if (isExcludedUrl(req.url) || !token) {
+    return next(req); // No modificar la solicitud
+  }
+
+  // Clonar la solicitud y agregar el token al encabezado si existe
+  const authReq = token
+    ? req.clone({
+        setHeaders: {
+          Authorization: `Bearer ${token.token}`,
+          'Content-Type': 'application/json',
+        },
+      })
+    : req;
+
+  // Pasar la solicitud modificada al siguiente manejador
+  return next(authReq);
+};
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts
index 5789a064b18d4aa50d9c6d9f163a87fb89bb7afc..6fb90798ea3a10e2dece5c0b0661e4a43ec393a4 100644
--- a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts
+++ b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts
@@ -7,7 +7,7 @@ import {
 import { FormsModule } from '@angular/forms';
 import { MatInputModule } from '@angular/material/input';
 import { MatSelectModule } from '@angular/material/select';
-import { Hotel, Room, RoomType, roomTypeArray } from '../../../../../types';
+import { Hotel, Room, RoomType, roomTypeArray } from '../../../../types';
 import { Router } from '@angular/router';
 import { MatCardModule } from '@angular/material/card';
 import { MatChipsModule } from '@angular/material/chips';
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts
index 9b99737e243b360d543e3ae57ff88d570a39a970..6ad8c379ae5b2e117c10a160eb07df12890f45fb 100644
--- a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts
+++ b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts
@@ -7,7 +7,7 @@ import {
 } from '@angular/forms';
 
 import { ActivatedRoute, Router } from '@angular/router';
-import { Booking, User } from '../../../../../types';
+import { Booking, User } from '../../../../types';
 import { LocalStorageService } from '../../../../shared/local-storage.service';
 import { BookingClientService } from '../../../../shared/booking-client.service';
 import { UserClientService } from '../../../../shared/user-client.service';
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts
index 1bcaf64719ede78b63593bf0c504db6bb263488d..d951865749ebd766b23898f9428d593341cd73d6 100644
--- a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts
@@ -1,6 +1,6 @@
 import { Component } from '@angular/core';
 import { RouterModule, Router } from '@angular/router';
-import { Hotel } from '../../../../../types';
+import { Hotel } from '../../../../types';
 import {
   MatAccordion,
   MatExpansionPanel,
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts
index fad7415511aa5a15fc72df3af768f77454f0018f..9e2c2d433b6fa68621be16b30b7841e34ec8829f 100644
--- a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts
@@ -13,7 +13,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
 import { MatSelectModule } from '@angular/material/select';
 import { MatSlideToggleModule } from '@angular/material/slide-toggle';
 import { CommonModule } from '@angular/common';
-import { Address, Hotel, Room } from '../../../../../types';
+import { Address, Hotel, Room } from '../../../../types';
 import { ActivatedRoute, Router } from '@angular/router';
 import { HotelClientService } from '../../../../shared/hotel-client.service';
 
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts
index e609b7e568a909e2d6f7efd995ddccb57472cb76..14b5a9d6c0e871d0e71b3d2154554f83e8ecc50d 100644
--- a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts
+++ b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts
@@ -1,11 +1,11 @@
-// main-page.component.ts
 import { Component, OnInit } from '@angular/core';
-import { User, UserStateFilter } from '../../../../../types';
+import { Client, User, UserStateFilter } from '../../../../types';
 import { FormsModule } from '@angular/forms';
 import { CommonModule } from '@angular/common';
-import users from '../../../../../mocks/users.json';
 import { RouterModule } from '@angular/router';
 import { UserClientService } from '../../../../shared/user-client.service';
+import { users } from '../../../../../mocks/users'; // Renombrado para claridad
+
 @Component({
   standalone: true,
   imports: [FormsModule, CommonModule, RouterModule],
@@ -14,23 +14,32 @@ import { UserClientService } from '../../../../shared/user-client.service';
   styleUrls: ['./main-page.component.css'],
 })
 export class MainPageComponent implements OnInit {
-  users: User[] = [];
-  filteredUsers: User[] = [];
+  users: Client[] = [];
+  filteredUsers: Client[] = [];
   selectedStatus: UserStateFilter = 'All';
 
   constructor(private userClient: UserClientService) {}
 
   ngOnInit(): void {
-    this.users = users as unknown as User[];
-    this.userClient.getAllUsers().subscribe((data: User[]) => {
-      this.users = data;
-      this.filteredUsers = data; // Inicialmente, muestra todos los usuarios
+    // Validar que el mock sea del tipo correcto
+    // const isValidMock = Array.isArray(mockUsers) && mockUsers.every(user => 'id' in user && 'name' in user && 'status' in user);
+    // this.users = isValidMock ? (mockUsers as User[]) : [];
+    this.users = users;
+    this.filteredUsers = [...this.users];
+
+    // Sobrescribir con datos reales si están disponibles
+    this.userClient.getAllUsers().subscribe({
+      next: (data: Client[]) => {
+        this.users = data;
+        this.filteredUsers = [...data];
+      },
+      error: (err) => console.error('Error al cargar usuarios:', err),
     });
   }
 
   filterUsers(): void {
     if (this.selectedStatus === 'All') {
-      this.filteredUsers = this.users;
+      this.filteredUsers = [...this.users];
     } else {
       this.filteredUsers = this.users.filter(
         (user) => user.status === this.selectedStatus
@@ -38,7 +47,7 @@ export class MainPageComponent implements OnInit {
     }
   }
 
-  getState(user: User) {
+  getState(user: Client): string {
     switch (user.status) {
       case 'NO_BOOKINGS':
         return 'SIN RESERVAS';
@@ -46,6 +55,8 @@ export class MainPageComponent implements OnInit {
         return 'CON RESERVAS ACTIVAS';
       case 'WITH_INACTIVE_BOOKINGS':
         return 'CON RESERVAS INACTIVAS';
+      default:
+        return 'ESTADO DESCONOCIDO';
     }
   }
 }
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts
index 10be15d9b999d3d0f2a370236507605df40b4bbd..878e6446e5bc8a162d67e880edd8633a5cbb3a94 100644
--- a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts
+++ b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts
@@ -1,6 +1,6 @@
 import { Component } from '@angular/core';
 
-import { Booking, User } from '../../../../../types';
+import { Booking, User } from '../../../../types';
 import { ActivatedRoute, RouterModule } from '@angular/router';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
@@ -44,7 +44,7 @@ export class UserBookingListComponent {
   }
 
   updateBookings() {
-    this.bookingClient.getUserBookings(this.userId).subscribe({
+    this.bookingClient.getBookingsByUser(this.userId).subscribe({
       next: (bookings) => {
         this.search = true;
         switch (this.selectedState) {
@@ -88,7 +88,7 @@ export class UserBookingListComponent {
   }
 
   updateUserStatus() {
-    this.bookingClient.getUserBookings(this.userId).subscribe({
+    this.bookingClient.getBookingsByUser(this.userId).subscribe({
       next: (bookings) => {
         const withActive = bookings.find(
           (booking) => this.genBookingState(booking) === 'Reserva activa'
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.css b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..1eef9bba18e0bd279742ea1d297e8ab49da1c394
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.css
@@ -0,0 +1,81 @@
+.form-container {
+  max-width: 400px;
+  margin: 50px auto;
+  background: #f8f9fa;
+  padding: 20px;
+  border-radius: 10px;
+  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+  font-family: Arial, sans-serif;
+}
+
+h2 {
+  text-align: center;
+  margin-bottom: 20px;
+  color: #333;
+}
+
+.form-group {
+  margin-bottom: 15px;
+}
+
+label {
+  display: block;
+  font-weight: bold;
+  margin-bottom: 5px;
+  color: #555;
+}
+
+input {
+  width: 100%;
+  padding: 10px;
+  font-size: 14px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  background: #fff;
+}
+
+input[readonly] {
+  background: #f3f3f3;
+}
+
+.button-group {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 20px;
+}
+
+.btn {
+  padding: 10px 20px;
+  font-size: 14px;
+  border: none;
+  border-radius: 5px;
+  cursor: pointer;
+  transition: background-color 0.3s ease;
+}
+
+.btn-primary {
+  background-color: #007bff;
+  color: white;
+}
+
+.btn-primary:hover {
+  background-color: #0056b3;
+}
+
+.btn-secondary {
+  background-color: #6c757d;
+  color: white;
+}
+
+.btn-secondary:hover {
+  background-color: #5a6268;
+}
+
+.btn-success {
+  background-color: #28a745;
+  color: white;
+}
+
+.btn-success:hover {
+  background-color: #218838;
+}
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.html b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..d68f32bfd2d6a14846503422e0273bc04effd127
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.html
@@ -0,0 +1,75 @@
+<div class="form-container">
+  <h2>Perfil de Usuario</h2>
+  <form [formGroup]="userForm" (ngSubmit)="saveChanges()">
+    <!-- Campo Nombre -->
+    <div class="form-group">
+      <label for="name">Nombre:</label>
+      <input
+        id="name"
+        type="text"
+        class="form-control"
+        formControlName="name"
+        [readonly]="!isEditing"
+      />
+    </div>
+
+    <!-- Campo Email -->
+    <div class="form-group">
+      <label for="email">Email:</label>
+      <input
+        id="email"
+        type="email"
+        class="form-control"
+        formControlName="email"
+        [readonly]="!isEditing"
+      />
+    </div>
+
+    @if (isEditing) {
+    <!-- Campo Contraseña Actual (solo en edición) -->
+    <div class="form-group">
+      <label for="currentPassword">Contraseña actual:</label>
+      <input
+        id="currentPassword"
+        type="password"
+        class="form-control"
+        formControlName="currentPassword"
+        placeholder="Introduce tu contraseña actual"
+      />
+    </div>
+
+    <!-- Campo Nueva Contraseña (solo en edición) -->
+    <div class="form-group">
+      <label for="newPassword">Nueva contraseña:</label>
+      <input
+        id="newPassword"
+        type="password"
+        class="form-control"
+        formControlName="newPassword"
+        placeholder="Introduce tu nueva contraseña"
+      />
+    </div>
+    }
+
+    <!-- Grupo de Botones -->
+    <div class="button-group">
+      @if (!isEditing) {
+      <button type="button" class="btn btn-primary" (click)="toggleEdit()">
+        Editar
+      </button>
+      } @else {
+      <button type="button" class="btn btn-secondary" (click)="cancelEdit()">
+        Cancelar
+      </button>
+
+      <button
+        type="submit"
+        class="btn btn-success"
+        [disabled]="!userForm.valid"
+      >
+        Guardar
+      </button>
+      }
+    </div>
+  </form>
+</div>
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.spec.ts b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..292f234075dbcba5482794cf23e4a231e666ba17
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.spec.ts
@@ -0,0 +1,91 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { HttpResponse } from '@angular/common/http';
+import { UserFormComponent } from './user-form.component';
+import { UserClientService } from '../../../../shared/user-client.service';
+import { of } from 'rxjs';
+
+describe('UserFormComponent', () => {
+  let component: UserFormComponent;
+  let fixture: ComponentFixture<UserFormComponent>;
+  let userService: UserClientService;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ReactiveFormsModule, FormsModule],
+      declarations: [UserFormComponent],
+      providers: [UserClientService],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(UserFormComponent);
+    component = fixture.componentInstance;
+    userService = TestBed.inject(UserClientService);
+
+    spyOn(userService, 'getCurrentUser').and.returnValue(
+      of({
+        id: 1,
+        name: 'John Doe',
+        email: 'johndoe@example.com',
+        rol: 'CONSUMER',
+        status: 'WITH_ACTIVE_BOOKINGS',
+      })
+    );
+
+    spyOn(userService, 'updateUser').and.returnValue(of(new HttpResponse({ body: 'User updated successfully' })));
+    spyOn(userService, 'updatePassword').and.returnValue(of(new HttpResponse({ body: 'Password updated successfully' })));
+
+    fixture.detectChanges();
+  });
+
+  it('should create the component', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should load user data on initialization', () => {
+    expect(component.userForm.value).toEqual({
+      name: 'John Doe',
+      email: 'johndoe@example.com',
+      password: '',
+      confirmPassword: '',
+    });
+  });
+
+  it('should call updateUser when saving valid user data', () => {
+    component.userForm.patchValue({
+      name: 'Jane Doe',
+      email: 'janedoe@example.com',
+    });
+
+    component.saveChanges();
+
+    expect(userService.updateUser).toHaveBeenCalledWith({
+      name: 'Jane Doe',
+      email: 'janedoe@example.com',
+    });
+  });
+
+  it('should call updatePassword when password is updated and matches confirmPassword', () => {
+    component.userForm.patchValue({
+      password: 'newpassword123',
+      confirmPassword: 'newpassword123',
+    });
+
+    component.saveChanges();
+
+    expect(userService.updatePassword).toHaveBeenCalledWith(
+      '',
+      'newpassword123'
+    );
+  });
+
+  it('should not call updatePassword if password and confirmPassword do not match', () => {
+    component.userForm.patchValue({
+      password: 'newpassword123',
+      confirmPassword: 'differentpassword',
+    });
+
+    component.saveChanges();
+
+    expect(userService.updatePassword).not.toHaveBeenCalled();
+  });
+});
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.ts b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..558e1c58a73e3d7ef1eaf852bce1a989a40bc42b
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-form/user-form.component.ts
@@ -0,0 +1,93 @@
+import { Component, OnInit } from '@angular/core';
+import {
+  FormBuilder,
+  FormGroup,
+  Validators,
+  ReactiveFormsModule,
+  FormsModule,
+} from '@angular/forms';
+import { UserClientService } from '../../../../shared/user-client.service';
+import { users } from '../../../../../mocks/users';
+import { ActivatedRoute } from '@angular/router';
+
+@Component({
+  standalone: true,
+  selector: 'app-user-form',
+  templateUrl: './user-form.component.html',
+  styleUrls: ['./user-form.component.css'],
+  imports: [ReactiveFormsModule, FormsModule],
+})
+export class UserFormComponent implements OnInit {
+  userForm!: FormGroup;
+  isEditing = false;
+  id = 0;
+
+  constructor(
+    private fb: FormBuilder,
+    private userService: UserClientService,
+    private route: ActivatedRoute
+  ) {}
+
+  ngOnInit(): void {
+    this.initializeForm();
+    this.route.paramMap.subscribe({
+      next: (params) => {
+        const id = Number(params.get('id'));
+        if (id) {
+          this.id = id;
+          this.isEditing = true;
+          this.loadUserData();
+        }
+      },
+    });
+  }
+
+  private initializeForm(): void {
+    this.userForm = this.fb.group({
+      name: [{ value: '', disabled: true }, Validators.required],
+      email: [
+        { value: '', disabled: true },
+        [Validators.required, Validators.email],
+      ],
+      currentPassword: [''], // Solo habilitado en modo edición
+      newPassword: [''], // Solo habilitado en modo edición
+    });
+  }
+
+  private loadUserData(): void {
+    // this.userService.getCurrentUser().subscribe((user) => {
+    console.log({ id: this.id });
+    users
+      .filter((u) => u.id == this.id)
+      .slice(0)
+      .map((user) => {
+        this.userForm.patchValue({
+          name: user.name,
+          email: user.email,
+        });
+      });
+  }
+
+  toggleEdit(): void {
+    this.isEditing = true;
+    this.userForm.get('name')?.enable();
+    this.userForm.get('email')?.enable();
+  }
+
+  cancelEdit(): void {
+    this.isEditing = false;
+    this.loadUserData(); // Volver a cargar los datos originales
+    this.userForm.get('name')?.disable();
+    this.userForm.get('email')?.disable();
+  }
+
+  saveChanges(): void {
+    if (this.userForm.valid) {
+      const updatedData = this.userForm.value;
+      this.userService.updateUser(updatedData).subscribe(() => {
+        this.isEditing = false;
+        this.loadUserData();
+      });
+    }
+  }
+}
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.css b/angular/RestClient/src/app/core/navigation/navigation.component.css
index 200c21a3a62ba294324b6a77c75d043c2bd5574b..e3b01c1fac3de8d58e16185d24ac3791394e7b67 100644
--- a/angular/RestClient/src/app/core/navigation/navigation.component.css
+++ b/angular/RestClient/src/app/core/navigation/navigation.component.css
@@ -4,7 +4,7 @@ nav {
   padding: 1em;
 }
 
-ul {
+ul.nav {
   list-style: none;
   padding: 0;
   display: flex;
@@ -14,15 +14,15 @@ li {
   margin-right: 20px;
 }
 
-a,
-a:visited {
+a.nav-link,
+a.nav-link:visited {
   color: white;
   text-decoration: none;
   transform: scale(1);
   transition: transform 0.3s ease;
 }
 
-a:hover {
+a.nav-link:hover {
   font-weight: bold;
   text-decoration: underline;
   color: yellow;
@@ -34,6 +34,12 @@ a:hover {
   font-weight: bold;
 }
 
+a.simple,
+a.simple:visited {
+  color: white;
+  text-decoration: none;
+}
+
 @keyframes escalar {
   0% {
     transform: scale(1);
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.html b/angular/RestClient/src/app/core/navigation/navigation.component.html
index 63615464cbbf7aec69cbd99e5e33ea9d1e5e08d8..94a99ba6dbf61fec024f7818dce9c8cc41115c6a 100644
--- a/angular/RestClient/src/app/core/navigation/navigation.component.html
+++ b/angular/RestClient/src/app/core/navigation/navigation.component.html
@@ -1,12 +1,72 @@
 <nav>
-  <ul>
-    <li><a class="btn" [routerLink]="['/']">Home - Usuarios</a></li>
+  <ul class="nav">
+    <li><a class="btn nav-link" [routerLink]="['/']">Home - Usuarios</a></li>
     <li>
-      <a class="btn" [routerLink]="['/hotels', 'new']">Registrar Hotel</a>
+      <a class="btn nav-link" [routerLink]="['/hotels', 'new']"
+        >Registrar Hotel</a
+      >
     </li>
-    <li><a class="btn" [routerLink]="['/hotels']">Hoteles</a></li>
+    <li><a class="btn nav-link" [routerLink]="['/hotels']">Hoteles</a></li>
     <li>
-      <a class="btn" [routerLink]="['/bookings', 'search']">Nueva Reserva</a>
+      <a class="btn nav-link" [routerLink]="['/bookings', 'search']"
+        >Nueva Reserva</a
+      >
+    </li>
+    <!-- Solucionar que no va -->
+    <!-- <li class="ml-auto"> -->
+    <li style="margin-left: auto">
+      @if (isLogged){
+      <!-- Dropdown para usuario registrado -->
+
+      <div class="btn bg-blue-500 text-white rounded hover:bg-blue-600">
+        <!-- mat-icon-button -->
+        <button
+          [matMenuTriggerFor]="sessionOptions"
+          class="flex items-center gap-3"
+        >
+          <span class="text-4xl">{{ user.name }}</span>
+
+          @if (trigger?.menuOpen) {
+          <mat-icon class="text-4xl">arrow_drop_up</mat-icon>
+          }@else {
+          <mat-icon class="text-4xl">arrow_drop_down</mat-icon>
+          }
+        </button>
+      </div>
+      <mat-menu #sessionOptions="matMenu" xPosition="before">
+        @for (section of sections; track section.id) { @if (section.link) {
+        <a [routerLink]="section.link" class="simple">
+          <button mat-menu-item>
+            <mat-icon>{{ section.icon }}</mat-icon>
+            <span class="text-2xl">{{ section.text }}</span>
+          </button>
+        </a>
+        } @else {
+        <button mat-menu-item>
+          <mat-icon>{{ section.icon }}</mat-icon>
+          <span class="text-2xl">{{ section.text }}</span>
+        </button>
+        } }
+        <button mat-menu-item (click)="logout()">
+          <mat-icon>logout</mat-icon>
+          <span class="text-2xl">Cerrar sesión</span>
+        </button>
+      </mat-menu>
+
+      } @else {
+      <div
+        class="btn bg-blue-500 text-white hover:bg-blue-600 ml-auto"
+        (click)="login()"
+      >
+        <!-- <a class="simple" [routerLink]="['/login']"> -->
+        <a class="simple">
+          <button class="flex items-center gap-3">
+            <span class="text-4xl">Login</span>
+            <mat-icon>login</mat-icon>
+          </button>
+        </a>
+      </div>
+      }
     </li>
   </ul>
 </nav>
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.ts b/angular/RestClient/src/app/core/navigation/navigation.component.ts
index ccdab77b49379e3ed27abd65ada67e693882939a..1e7a72d5eb50276981b4f00a3950847105e06f0d 100644
--- a/angular/RestClient/src/app/core/navigation/navigation.component.ts
+++ b/angular/RestClient/src/app/core/navigation/navigation.component.ts
@@ -1,10 +1,122 @@
-import { Component } from '@angular/core';
-import { Router, RouterModule } from '@angular/router';
+import { OnInit, Component, ViewChild } from '@angular/core';
+import { RouterModule } from '@angular/router';
+import { MatButtonModule } from '@angular/material/button';
+import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
+import { MatIconModule } from '@angular/material/icon';
+import { User, UserRol } from '../../types';
+import { AuthInstance, SessionService } from '../../shared/session.service';
+import { UserClientService } from '../../shared/user-client.service';
+import { AuthClientService } from '../../shared/auth-client.service';
+
+var comp_id = 0;
+
+export function genId() {
+  const comp = 'navigation';
+  return `${comp}-${comp_id++}`;
+}
+
+interface Section {
+  id: string;
+  icon: string;
+  text: string;
+  link: string;
+  allowRoles?: UserRol[];
+}
+
 @Component({
   selector: 'app-navigation',
   standalone: true,
-  imports: [RouterModule],
+  imports: [RouterModule, MatButtonModule, MatMenuModule, MatIconModule],
   templateUrl: './navigation.component.html',
   styleUrl: './navigation.component.css',
 })
-export class NavigationComponent {}
+export class NavigationComponent implements OnInit {
+  @ViewChild(MatMenuTrigger)
+  trigger?: MatMenuTrigger;
+  isLogged = false;
+  user: AuthInstance = {
+    id: 0,
+    name: '',
+    email: '',
+    rol: 'CLIENT',
+  };
+  sections: Section[] = [];
+
+  constructor(
+    private sessionService: SessionService,
+    private auth: AuthClientService
+  ) {}
+
+  ngOnInit() {
+    this.loadUser();
+  }
+
+  loadUser() {
+    const isLogged = this.sessionService.isValid();
+    if (isLogged) {
+      this.user = this.sessionService.getSession();
+      console.log({ user: this.user });
+      this.sections = this.genSections();
+    }
+    this.isLogged = isLogged;
+  }
+
+  toggleDropdown() {
+    if (this.trigger) {
+      if (this.trigger.menuOpen) this.trigger.closeMenu();
+      else this.trigger.openMenu();
+    }
+  }
+
+  schemaSections: Section[] = [
+    {
+      id: genId(),
+      icon: 'person',
+      text: 'Información personal',
+      link: '/me',
+    },
+    {
+      id: genId(),
+      icon: 'calendar_today',
+      text: 'Reservas',
+      allowRoles: ['CLIENT'],
+      link: '/users/1/bookings',
+      // link: '/bookings',
+    },
+    {
+      id: genId(),
+      icon: 'hotel',
+      text: 'Hoteles',
+      allowRoles: ['HOTEL_ADMIN'],
+      link: '/hotels',
+    },
+  ];
+
+  genSections() {
+    return this.schemaSections.filter(
+      (section) =>
+        this.user.rol === 'ADMIN' || // Es administrador del sistema
+        !section.allowRoles ||
+        section.allowRoles.length === 0 || // No tiene limitación
+        section.allowRoles.includes(this.user.rol) // El rol del usuario es aceptado
+    );
+  }
+
+  login() {
+    const email = 'client@dev.com';
+    this.auth.login(email, 'NQSASorry').subscribe({
+      next: (data: any) => {
+        console.log(email, data);
+        this.sessionService.login(data);
+        this.loadUser();
+      },
+    });
+  }
+
+  logout() {
+    if (confirm('You are trying to logout')) {
+      this.sessionService.logout();
+      this.loadUser();
+    }
+  }
+}
diff --git a/angular/RestClient/src/app/shared/auth-client.service.ts b/angular/RestClient/src/app/shared/auth-client.service.ts
index ec3280b68da6db216a68e72c8847e5fee4e6b04d..931fc7dbacbec3db5e5d048722fa5980017355e7 100644
--- a/angular/RestClient/src/app/shared/auth-client.service.ts
+++ b/angular/RestClient/src/app/shared/auth-client.service.ts
@@ -1,5 +1,6 @@
 import { Injectable } from '@angular/core';
-import { environment } from '../../environments/environment';
+import { environment } from '../../../environments/environment';
+import { HttpClient } from '@angular/common/http';
 
 @Injectable({
   providedIn: 'root',
@@ -7,5 +8,39 @@ import { environment } from '../../environments/environment';
 export class AuthClientService {
   private readonly URI = environment.authAPI;
 
-  constructor() {}
+  constructor(private http: HttpClient) {}
+
+  login(email: String, password: String) {
+    return this.http.post(
+      `${this.URI}/login`,
+      { email, password }
+      // {
+      //   headers: {
+      //     'Content-Type': 'application/json',
+      //     'Access-Control-Allow-Origin': '*',
+      //     'Access-Control-Allow-Methods':
+      //       'GET, POST, OPTIONS, PUT, PATCH, DELETE',
+      //     'Access-Control-Allow-Headers': 'X-Requested-With,content-type',
+      //     'Access-Control-Allow-Credentials': 'true',
+      //   },
+      // }
+    );
+  }
+
+  register(name: String, email: String, password: String, rol?: String) {
+    return this.http.post(
+      `${this.URI}/register`,
+      {
+        name,
+        email,
+        password,
+        rol,
+      },
+      {
+        headers: {
+          'Content-Type': 'application/json',
+        },
+      }
+    );
+  }
 }
diff --git a/angular/RestClient/src/app/shared/booking-client.service.ts b/angular/RestClient/src/app/shared/booking-client.service.ts
index 7d38299878b9a5500ade1883c47d08585ca01ebb..3e44163b0944263f937334320090ec3ee2ef786e 100644
--- a/angular/RestClient/src/app/shared/booking-client.service.ts
+++ b/angular/RestClient/src/app/shared/booking-client.service.ts
@@ -1,8 +1,8 @@
 import { Injectable } from '@angular/core';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Observable } from 'rxjs';
-import { environment } from '../../environments/environment';
-import { Booking } from '../../types/Booking'; // Ajusta la ruta a tu modelo Booking
+import { environment } from '../../../environments/environment';
+import { Booking } from '../types/Booking'; // Ajusta la ruta a tu modelo Booking
 
 @Injectable({
   providedIn: 'root',
@@ -31,9 +31,8 @@ export class BookingClientService {
     return this.http.get<Booking>(`${this.URI}/${id}`);
   }
 
-  getUserBookings(userId: number) {
-    // TODO revisar tras división en microservicios
-    return this.http.get<Booking[]>(`${this.URI}/${userId}/bookings`);
+  getBookingsByUser(userId: number) {
+    return this.http.get<Booking[]>(`${this.URI}?userId=${userId}`);
   }
 
   // Método para eliminar una reserva
diff --git a/angular/RestClient/src/app/shared/hotel-client.service.ts b/angular/RestClient/src/app/shared/hotel-client.service.ts
index f00b3e6d5259866c895bffa7856e8e838ae85deb..87756a392895ecc95b745101b7accaef0e20a3e1 100644
--- a/angular/RestClient/src/app/shared/hotel-client.service.ts
+++ b/angular/RestClient/src/app/shared/hotel-client.service.ts
@@ -1,7 +1,7 @@
 import { Injectable } from '@angular/core';
-import { environment } from '../../environments/environment';
+import { environment } from '../../../environments/environment';
 import { HttpClient } from '@angular/common/http';
-import { Hotel, Room } from '../../types';
+import { Hotel, Room } from '../types';
 
 @Injectable({
   providedIn: 'root',
diff --git a/angular/RestClient/src/app/shared/local-storage.service.ts b/angular/RestClient/src/app/shared/local-storage.service.ts
index e1526f8aaa1b56903668de93697f4a2b072d97ab..dc328655c80df4c87132a25305026eb3f00d1fec 100644
--- a/angular/RestClient/src/app/shared/local-storage.service.ts
+++ b/angular/RestClient/src/app/shared/local-storage.service.ts
@@ -1,32 +1,21 @@
-import { isPlatformBrowser } from '@angular/common';
-import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
+import { Injectable } from '@angular/core';
 
 @Injectable({
   providedIn: 'root',
 })
 export class LocalStorageService {
-  // isBrowser: boolean;
-
-  // constructor(@Inject(PLATFORM_ID) private platformId: Object) {
-  //   this.isBrowser = isPlatformBrowser(this.platformId);
-  // }
-
-  save(key: string, value: any) {
-    // if (!this.isBrowser) return;
-    localStorage.setItem(key, JSON.stringify(value));
+  save(key: string, value: object) {
+    const content = JSON.stringify(value);
+    localStorage.setItem(key, content);
   }
 
   read<T>(key: string) {
-    // if (!this.isBrowser) return null;
-
     const json = localStorage.getItem(key);
     const ret = json ? (JSON.parse(json) as T) : null;
     return ret;
   }
 
   consume<T>(key: string) {
-    // if (!this.isBrowser) return null;
-
     const value = this.read<T>(key);
     if (value !== null) {
       this.remove(key);
@@ -35,8 +24,6 @@ export class LocalStorageService {
   }
 
   remove(key: string) {
-    // if (!this.isBrowser) return;
-
     localStorage.removeItem(key);
   }
 }
diff --git a/angular/RestClient/src/app/shared/session.service.spec.ts b/angular/RestClient/src/app/shared/session.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4238e142b07aad273072a64a6df73c7960707501
--- /dev/null
+++ b/angular/RestClient/src/app/shared/session.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { SessionService } from './session.service';
+
+describe('SessionService', () => {
+  let service: SessionService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(SessionService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/shared/session.service.ts b/angular/RestClient/src/app/shared/session.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..82e9daaceed948aa6ed973b710f704421f5b30f5
--- /dev/null
+++ b/angular/RestClient/src/app/shared/session.service.ts
@@ -0,0 +1,58 @@
+import { Injectable } from '@angular/core';
+import { LocalStorageService } from './local-storage.service';
+import { UserRol } from '../types';
+
+import { jwtDecode } from 'jwt-decode';
+
+export interface AuthInstance {
+  id: number;
+  name: string;
+  email: string;
+  rol: UserRol;
+}
+
+interface PersistenToken {
+  token: string;
+}
+
+@Injectable({
+  providedIn: 'root',
+})
+export class SessionService {
+  constructor(private storage: LocalStorageService) {}
+
+  private tokenKey = 'token';
+
+  login(session: PersistenToken) {
+    this.storage.save(this.tokenKey, session);
+  }
+
+  logout() {
+    this.storage.remove(this.tokenKey);
+  }
+
+  getToken() {
+    const savedToken = this.storage.read<PersistenToken>(this.tokenKey);
+    if (!savedToken) throw new Error('No session');
+    return savedToken.token;
+  }
+
+  getSession() {
+    const token = this.getToken();
+    const r = jwtDecode<{ user: AuthInstance }>(token);
+    return r.user;
+  }
+
+  isLogged() {
+    return !!this.storage.read<PersistenToken>(this.tokenKey);
+  }
+
+  isValid() {
+    console.warn({ log: this.isLogged() });
+    if (!this.isLogged()) return false;
+    const token = this.getToken();
+    const r = jwtDecode(token);
+    // Validate if the token have been expired or not
+    return r.exp! > Math.floor(Date.now() / 1000);
+  }
+}
diff --git a/angular/RestClient/src/app/shared/user-client.service.ts b/angular/RestClient/src/app/shared/user-client.service.ts
index ea51f7e5060cf349c86159e981748a028806ef80..2b2592e00c49b292df6799a76b4a6feb95b48380 100644
--- a/angular/RestClient/src/app/shared/user-client.service.ts
+++ b/angular/RestClient/src/app/shared/user-client.service.ts
@@ -1,25 +1,29 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
-import { environment } from '../../environments/environment';
-import { User, UserState } from '../../types';
+import { environment } from '../../../environments/environment';
+import { Client, User, UserState } from '../types';
 
 @Injectable({
   providedIn: 'root',
 })
 export class UserClientService {
   private readonly URI = environment.userAPI;
+
   constructor(private http: HttpClient) {}
 
+  // Obtener un usuario por ID
   getUser(userId: number) {
     return this.http.get<User>(`${this.URI}/${userId}`);
   }
 
+  // Obtener todos los usuarios
   getAllUsers() {
-    return this.http.get<User[]>(this.URI, {
+    return this.http.get<Client[]>(this.URI, {
       observe: 'body',
     });
   }
 
+  // Cambiar estado de un usuario
   alterUserStatus(userId: number, status: UserState) {
     return this.http.patch(
       `${this.URI}/${userId}`,
@@ -32,4 +36,29 @@ export class UserClientService {
       }
     );
   }
+
+  // Obtener el usuario actual (autenticado)
+  getCurrentUser() {
+    return this.http.get<User>(`${this.URI}/me`);
+  }
+
+  // Actualizar los datos del usuario
+  updateUser(user: Partial<User>) {
+    return this.http.patch(`${this.URI}/me`, user, {
+      observe: 'response',
+      responseType: 'text',
+    });
+  }
+
+  // Cambiar la contraseña del usuario
+  updatePassword(currentPassword: string, newPassword: string) {
+    return this.http.patch(
+      `${this.URI}/me/password`,
+      { currentPassword, newPassword },
+      {
+        observe: 'response',
+        responseType: 'text',
+      }
+    );
+  }
 }
diff --git a/angular/RestClient/src/types/Address.d.ts b/angular/RestClient/src/app/types/Address.d.ts
similarity index 100%
rename from angular/RestClient/src/types/Address.d.ts
rename to angular/RestClient/src/app/types/Address.d.ts
diff --git a/angular/RestClient/src/types/Booking.d.ts b/angular/RestClient/src/app/types/Booking.d.ts
similarity index 100%
rename from angular/RestClient/src/types/Booking.d.ts
rename to angular/RestClient/src/app/types/Booking.d.ts
diff --git a/angular/RestClient/src/types/Hotel.d.ts b/angular/RestClient/src/app/types/Hotel.d.ts
similarity index 100%
rename from angular/RestClient/src/types/Hotel.d.ts
rename to angular/RestClient/src/app/types/Hotel.d.ts
diff --git a/angular/RestClient/src/types/Room.d.ts b/angular/RestClient/src/app/types/Room.d.ts
similarity index 100%
rename from angular/RestClient/src/types/Room.d.ts
rename to angular/RestClient/src/app/types/Room.d.ts
diff --git a/angular/RestClient/src/types/User.d.ts b/angular/RestClient/src/app/types/User.d.ts
similarity index 51%
rename from angular/RestClient/src/types/User.d.ts
rename to angular/RestClient/src/app/types/User.d.ts
index 1ecc3d7512e7ff0b644e5555d290c48e88518219..277f806a74fb1b2f854d733cc10acca67f18b840 100644
--- a/angular/RestClient/src/types/User.d.ts
+++ b/angular/RestClient/src/app/types/User.d.ts
@@ -2,10 +2,20 @@ export interface User {
   id: number;
   name: string;
   email: String;
-  // status: "noBookings" | "withActiveBookings" | "withInactiveBookings";
+  rol: UserRol;
+}
+
+export interface Client extends User {
   status: UserState;
+  // bookings: number[] // Booking[]
 }
 
+export interface HotelAdmin extends User {
+  // hotels: number[] // Hotel[]
+}
+
+export type UserRol = 'ADMIN' | 'CLIENT' | 'HOTEL_ADMIN';
+
 export type UserStateFilter = 'All' | UserState;
 
 export type UserState =
diff --git a/angular/RestClient/src/types/index.ts b/angular/RestClient/src/app/types/index.ts
similarity index 100%
rename from angular/RestClient/src/types/index.ts
rename to angular/RestClient/src/app/types/index.ts
diff --git a/angular/RestClient/src/environments/environment.monolith.ts b/angular/RestClient/src/environments/environment.monolith.ts
deleted file mode 100644
index 676025533ad47d166dedf355b0a08f5e8a96e904..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/environments/environment.monolith.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-// Simple -> Un servicio fachada / monolito
-const hostname = 'http://localhost:8080';
-
-export const environment = {
-  production: false,
-  authAPI: `${hostname}/auth`,
-  userAPI: `${hostname}/users`,
-  hotelAPI: `${hostname}/hotels`,
-  bookingAPI: `${hostname}/bookings`,
-};
diff --git a/angular/RestClient/src/environments/environment.prod.ts b/angular/RestClient/src/environments/environment.prod.ts
deleted file mode 100644
index 9318edcf83573d82d0005c135849aca26dc609a2..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/environments/environment.prod.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-// Disgregado en microservicios
-export const environment = {
-  production: true,
-  authAPI: 'http://auth-api:8080',
-  userAPI: 'http://users-api:8080',
-  hotelAPI: 'http://hotels-api:8080',
-  bookingAPI: 'http://bookings-api:8080',
-};
diff --git a/angular/RestClient/src/environments/environment.ts b/angular/RestClient/src/environments/environment.ts
deleted file mode 100644
index b5fe467280faf9259227fb281e401cff79c5aa87..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/environments/environment.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-// Disgregado en microservicios
-export const environment = {
-  production: false,
-  authAPI: 'http://localhost:8101',
-  userAPI: 'http://localhost:8111',
-  hotelAPI: 'http://localhost:8121',
-  bookingAPI: 'http://localhost:8131',
-};
diff --git a/angular/RestClient/src/mocks/bookings.json b/angular/RestClient/src/mocks/bookings.json
deleted file mode 100644
index 7db55ff76f1627de21762d95a7732a4f7be1ce34..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/mocks/bookings.json
+++ /dev/null
@@ -1,30 +0,0 @@
-[
-  {
-    "user": {
-      "name": "John Doe",
-      "email": "john.doe@example.com",
-      "status": "NO_BOOKINGS"
-    },
-    "room": {
-      "roomNumber": "101",
-      "type": "SINGLE",
-      "available": true
-    },
-    "startDate": "2024-03-01",
-    "endDate": "2024-03-08"
-  },
-  {
-    "user": {
-      "name": "Pepe",
-      "email": "pepe@example.com",
-      "status": "WITH_ACTIVE_BOOKINGS"
-    },
-    "room": {
-      "roomNumber": "101",
-      "type": "SINGLE",
-      "available": true
-    },
-    "startDate": "2024-03-15",
-    "endDate": "2024-03-22"
-  }
-]
diff --git a/angular/RestClient/src/mocks/hotels.json b/angular/RestClient/src/mocks/hotels.json
deleted file mode 100644
index 11381112f37ac1123d22f06a2a0526c07825f211..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/mocks/hotels.json
+++ /dev/null
@@ -1,46 +0,0 @@
-[
-  {
-    "id": 1,
-    "name": "Hotel 1",
-    "address": {
-      "id": 1,
-      "streetName": "Aca al lao",
-      "streetKind": "Alargada",
-      "number": 12,
-      "postCode": "12345"
-    },
-    "rooms": [
-      {
-        "id": 1,
-        "roomNumber": "101",
-        "type": "SINGLE",
-        "available": true
-      },
-      {
-        "id": 2,
-        "roomNumber": "102",
-        "type": "DOUBLE",
-        "available": false
-      }
-    ]
-  },
-  {
-    "id": 2,
-    "name": "Hotel 2",
-    "address": {
-      "id": 2,
-      "streetName": "Calle de la plaza",
-      "streetKind": "Alargada",
-      "number": 12,
-      "postCode": "12345"
-    },
-    "rooms": [
-      {
-        "id": 3,
-        "roomNumber": "103",
-        "type": "SUITE",
-        "available": true
-      }
-    ]
-  }
-]
diff --git a/angular/RestClient/src/mocks/users.json b/angular/RestClient/src/mocks/users.json
deleted file mode 100644
index 2f02d00125b0deaa2a86db47ea26f0c91f2e5fa3..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/mocks/users.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
-  {
-    "name": "John Doe",
-    "email": "john.doe@example.com",
-    "status": "NO_BOOKINGS"
-  },
-  {
-    "name": "Pepe",
-    "email": "pepe@example.com",
-    "status": "WITH_ACTIVE_BOOKINGS"
-  }
-]
diff --git a/angular/RestClient/src/mocks/users.ts b/angular/RestClient/src/mocks/users.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f6fafe67e13993f0e5b1a48c5443d43f6d3c2c3d
--- /dev/null
+++ b/angular/RestClient/src/mocks/users.ts
@@ -0,0 +1,18 @@
+import { Client, User } from '../app/types';
+
+export const users: Client[] = [
+  {
+    id: 1,
+    name: 'John Doe',
+    email: 'jon@com',
+    rol: 'CLIENT',
+    status: 'NO_BOOKINGS',
+  },
+  {
+    id: 2,
+    name: 'Angela Doe',
+    email: 'angle@com',
+    rol: 'CLIENT',
+    status: 'NO_BOOKINGS',
+  },
+];
diff --git a/docker-compose.yml b/docker-compose.yml
index 40484328bc7cb6aa6b3d94b2616393b3e0cab264..85641c264792a1c3cafb824d8b0b4337f2764ad1 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -8,7 +8,7 @@ networks:
 services:
   Auth-API:
     image: auth-api-image
-    hostname: ${AUTH_SERVICE_HOSTNAME}
+    hostname: $${AUTH_SERVICE_HOSTNAME}
     build:
       context: ./java/services/auth
       dockerfile: Dockerfile
@@ -18,13 +18,13 @@ services:
     networks:
       - kong-net
     environment:
-      SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
+      SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
     depends_on:
       - RoomsBooking-database
 
   Users-API:
     image: users-api-image
-    hostname: "${USERS_SERVICE_HOSTNAME}"
+    hostname: "$${USERS_SERVICE_HOSTNAME}"
     build:
       context: ./java/services/users
       dockerfile: Dockerfile
@@ -34,13 +34,13 @@ services:
     networks:
       - kong-net
     environment:
-      SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
+      SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
     depends_on:
       - RoomsBooking-database
 
   Hotels-API:
     image: hotels-api-image
-    hostname: ${HOTELS_SERVICE_HOSTNAME}
+    hostname: $${HOTELS_SERVICE_HOSTNAME}
     build:
       context: ./java/services/hotels
       dockerfile: Dockerfile
@@ -50,16 +50,16 @@ services:
     networks:
       - kong-net
     environment:
-      SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
-      SPRING_DATASOURCE_USER: ${USER_DATABASE}
-      SPRING_DATASOURCE_PASSWORD: ${}
+      SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
+      SPRING_DATASOURCE_USER: $${USER_DATABASE}
+      SPRING_DATASOURCE_PASSWORD: $${}
     depends_on:
       - RoomsBooking-database
       - Bookings-API
 
   Bookings-API:
     image: bookings-api-image
-    hostname: ${BOOKINGS_SERVICE_HOSTNAME}
+    hostname: $${BOOKINGS_SERVICE_HOSTNAME}
     build:
       context: ./java/services/bookings
       dockerfile: Dockerfile
@@ -69,13 +69,13 @@ services:
     networks:
       - kong-net
     environment:
-      SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
+      SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
     depends_on:
       - RoomsBooking-database
 
   RoomsBooking-database:
     image: mysql
-    hostname: ${DB_SERVICE_HOSTNAME}
+    hostname: $${DB_SERVICE_HOSTNAME}
     cap_add:
       - SYS_NICE
     restart: unless-stopped
@@ -103,6 +103,6 @@ services:
     networks:
       - kong-net
     environment:
-      SPRING_DATASOURCE_URL: jdbc:mysql://${DB_SERVICE_HOSTNAME}:3306/${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
+      SPRING_DATASOURCE_URL: jdbc:mysql://$${DB_SERVICE_HOSTNAME}:3306/$${DB_DATABASE_NAME}?createDatabaseIfNotExist=true
     depends_on:
       - RoomsBooking-database
diff --git a/java/roomBooking/pom.xml b/java/roomBooking/pom.xml
index 476f735b695a459292a258d72d89261c89dca993..f6fa75bdb21b812320db5afa07b770891fb9bd95 100644
--- a/java/roomBooking/pom.xml
+++ b/java/roomBooking/pom.xml
@@ -49,6 +49,32 @@
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-starter-security</artifactId>
+	</dependency>
+	<dependency>
+		<groupId>io.jsonwebtoken</groupId>
+		<artifactId>jjwt-api</artifactId>
+		<version>0.11.5</version>
+	</dependency>
+	<dependency>
+		<groupId>io.jsonwebtoken</groupId>
+		<artifactId>jjwt-impl</artifactId>
+		<version>0.11.5</version>
+		<scope>runtime</scope>
+	</dependency>
+	<dependency>
+		<groupId>io.jsonwebtoken</groupId>
+		<artifactId>jjwt-jackson</artifactId>
+		<version>0.11.5</version>
+		<scope>runtime</scope>
+	</dependency>
+	<dependency>
+        <groupId>jakarta.servlet</groupId>
+        <artifactId>jakarta.servlet-api</artifactId>
+        <scope>provided</scope>
+    </dependency>
 	</dependencies>
 
 	<build>
@@ -60,4 +86,4 @@
 		</plugins>
 	</build>
 
-</project>
+</project>
\ No newline at end of file
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/RoomBookingApplication.java b/java/roomBooking/src/main/java/com/uva/monolith/RoomBookingApplication.java
similarity index 90%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/RoomBookingApplication.java
rename to java/roomBooking/src/main/java/com/uva/monolith/RoomBookingApplication.java
index 1a5f312d49b2d1db4ffe587e4ae02c35e1e9a506..0a5db248da6e6be909302e323931f79151b0ed62 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/RoomBookingApplication.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/RoomBookingApplication.java
@@ -1,4 +1,4 @@
-package com.uva.roomBooking;
+package com.uva.monolith;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/config/SecurityConfig.java b/java/roomBooking/src/main/java/com/uva/monolith/config/SecurityConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cc2695222079be62bcb16f493158c0452920569
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/config/SecurityConfig.java
@@ -0,0 +1,46 @@
+package com.uva.monolith.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+import com.uva.monolith.filter.JwtAuthenticationFilter;
+import com.uva.monolith.services.users.models.UserRol;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig {
+
+    private final JwtAuthenticationFilter jwtAuthenticationFilter;
+
+    public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
+        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
+    }
+
+    @Bean
+    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+        http.csrf(csrf -> csrf.disable())
+                .authorizeHttpRequests(authorize -> authorize
+                        // Permitir OPTIONS sin autenticación
+                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
+                        // Acceso restringido a usuarios y administradores
+                        .requestMatchers("users", "users/**")
+                        .hasAnyRole(UserRol.ADMIN.toString(), UserRol.CLIENT.toString())
+                        // Acceso restringido a gestores de hoteles y administradores
+                        .requestMatchers("hotels", "hotels/**")
+                        .hasAnyRole(UserRol.ADMIN.toString(), UserRol.HOTEL_ADMIN.toString())
+                        // Acceso restringido a cualquier usuario del sistema
+                        .requestMatchers("bookings", "bookings/**")
+                        .hasAnyRole(UserRol.ADMIN.toString(), UserRol.HOTEL_ADMIN.toString(), UserRol.CLIENT.toString())
+                        // Rechazar el resto
+                        .anyRequest().denyAll())
+                // Registra el filtro antes del filtro estándar de autenticación
+                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+
+        return http.build();
+    }
+}
diff --git a/java/services/users/src/main/java/com/uva/users/Exceptions/GlobalExceptionHandler.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/GlobalExceptionHandler.java
similarity index 98%
rename from java/services/users/src/main/java/com/uva/users/Exceptions/GlobalExceptionHandler.java
rename to java/roomBooking/src/main/java/com/uva/monolith/exceptions/GlobalExceptionHandler.java
index 0e43ff06348e770f579e48bcbf056521f7f37da8..9428c51a9c63c3623d44752c9e3cbe6cf78ac19f 100644
--- a/java/services/users/src/main/java/com/uva/users/Exceptions/GlobalExceptionHandler.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/GlobalExceptionHandler.java
@@ -1,4 +1,4 @@
-package com.uva.users.Exceptions;
+package com.uva.monolith.exceptions;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/HotelNotFoundException.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/HotelNotFoundException.java
similarity index 89%
rename from java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/HotelNotFoundException.java
rename to java/roomBooking/src/main/java/com/uva/monolith/exceptions/HotelNotFoundException.java
index 4da802a0c6bc552386705da734c953d5a467fa70..129a0b1086b4b78eb1f1725b9f241f51ce5540f8 100644
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/HotelNotFoundException.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/HotelNotFoundException.java
@@ -1,4 +1,4 @@
-package com.uva.hotelService.Exceptions;
+package com.uva.monolith.exceptions;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.ResponseStatus;
diff --git a/java/services/users/src/main/java/com/uva/users/Exceptions/InvalidDateRangeException.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidDateRangeException.java
similarity index 80%
rename from java/services/users/src/main/java/com/uva/users/Exceptions/InvalidDateRangeException.java
rename to java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidDateRangeException.java
index 7cf94e38ed83bc5cc1a10d67f6c48eb8c9b42a66..5fea986ef1e9279c459bc5aff10932049f283333 100644
--- a/java/services/users/src/main/java/com/uva/users/Exceptions/InvalidDateRangeException.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidDateRangeException.java
@@ -1,8 +1,7 @@
-package com.uva.users.Exceptions;
+package com.uva.monolith.exceptions;
 
 public class InvalidDateRangeException extends RuntimeException {
     public InvalidDateRangeException(String message) {
         super(message);
     }
 }
-
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/InvalidRequestException.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidRequestException.java
similarity index 88%
rename from java/services/bookings/src/main/java/com/uva/bookings/Exceptions/InvalidRequestException.java
rename to java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidRequestException.java
index 76432c4e307148cb13288a969cf755606e76428b..ca09e054420dd174c4d2c3424dcc8fe74b6c8576 100644
--- a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/InvalidRequestException.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidRequestException.java
@@ -1,4 +1,4 @@
-package com.uva.bookings.Exceptions;
+package com.uva.monolith.exceptions;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.ResponseStatus;
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/filter/JwtAuthenticationFilter.java b/java/roomBooking/src/main/java/com/uva/monolith/filter/JwtAuthenticationFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b31d1a0e80f529075ef20bc4e9a955cfa825d30
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/filter/JwtAuthenticationFilter.java
@@ -0,0 +1,124 @@
+package com.uva.monolith.filter;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.MalformedJwtException;
+import io.jsonwebtoken.UnsupportedJwtException;
+import io.jsonwebtoken.io.Decoders;
+import io.jsonwebtoken.security.Keys;
+import io.jsonwebtoken.security.SignatureException;
+
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+
+import com.uva.monolith.services.users.models.UserRol;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.Filter;
+import java.io.IOException;
+import java.security.Key;
+import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.Date;
+
+@Component
+public class JwtAuthenticationFilter implements Filter {
+
+    private final String SECRET_KEY = "3cfa76ef14937c1c0ea519f8fc057a80fcd04a7420f8e8bcd0a7567c272e007b";
+
+    private Key getSignInKey() {
+        byte[] keyBytes = Decoders.BASE64.decode(SECRET_KEY);
+        return Keys.hmacShaKeyFor(keyBytes);
+    }
+
+    private String getTokenFromRequest(HttpServletRequest request) {
+        String authHeader = request.getHeader("Authorization");
+        if (authHeader == null || !authHeader.startsWith("Bearer "))
+            return null;
+        return authHeader.substring(7);
+    }
+
+    private Claims getClaimsFromToken(String token) {
+        return Jwts.parserBuilder()
+                .setSigningKey(getSignInKey())
+                .build()
+                .parseClaimsJws(token)
+                .getBody();
+    }
+
+    private boolean validateToken(String token) {
+        if (token == null)
+            return false;// no token
+        try {
+            // Verifica y analiza el token
+            Claims claims = getClaimsFromToken(token);
+
+            // Verifica que el token no esté expirado
+            return claims.getExpiration().after(new Date());
+        } catch (ExpiredJwtException e) {
+            System.out.println("[" + LocalDateTime.now().toString() + "] Token expirado: " + e.getMessage());
+        } catch (UnsupportedJwtException e) {
+            System.out.println("[" + LocalDateTime.now().toString() + "] Token no soportado: " + e.getMessage());
+        } catch (MalformedJwtException e) {
+            System.out.println("[" + LocalDateTime.now().toString() + "] Token malformado: " + e.getMessage());
+        } catch (SignatureException e) {
+            System.out.println("[" + LocalDateTime.now().toString() + "] Firma inválida: " + e.getMessage());
+        } catch (IllegalArgumentException e) {
+            System.out.println("[" + LocalDateTime.now().toString() + "] Token vacío o nulo: " + e.getMessage());
+        }
+        return false; // Si ocurre cualquier excepción, el token es inválido
+
+    }
+
+    private String getEmailFromToken(String token) {
+        return getClaimsFromToken(token).getSubject();
+    }
+
+    private UserRol getRoleFromToken(String token) {
+        String rol = getClaimsFromToken(token).get("rol", String.class);
+        return UserRol.valueOf(rol);
+    }
+
+    public static String getRol(UserRol rol) {
+        return String.format("ROLE_%s", rol.toString());
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+        String token = getTokenFromRequest(httpRequest);
+
+        System.out.println("[" + LocalDateTime.now().toString() + "] TOKEN " + token);
+
+        if (validateToken(token)) {
+
+            String email = getEmailFromToken(token);
+            UserRol role = getRoleFromToken(token); // Extraer el rol del token
+
+            if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) {
+                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
+                        email, null, null);
+                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
+                SecurityContextHolder.getContext().setAuthentication(authentication);
+            }
+
+            // Agregar el rol como autoridad
+            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(getRol(role));
+            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(email, null,
+                    Collections.singletonList(authority));
+            SecurityContextHolder.getContext().setAuthentication(authentication);
+        }
+
+        chain.doFilter(request, response);
+    }
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/controllers/BookingController.java b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/controllers/BookingController.java
new file mode 100644
index 0000000000000000000000000000000000000000..602f16a2f96e27d3e855440136cbcb41f9b57ab0
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/controllers/BookingController.java
@@ -0,0 +1,51 @@
+package com.uva.monolith.services.bookings.controllers;
+
+import com.uva.monolith.services.bookings.models.Booking;
+import com.uva.monolith.services.bookings.services.BookingService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@RestController
+@RequestMapping("/bookings")
+@CrossOrigin(origins = "*")
+public class BookingController {
+
+    private final BookingService bookingService;
+
+    public BookingController(BookingService bookingService) {
+        this.bookingService = bookingService;
+    }
+
+    @GetMapping
+    public List<Booking> getAllBookings(
+            @RequestParam(required = false) LocalDate start,
+            @RequestParam(required = false) LocalDate end,
+            @RequestParam(required = false) Integer roomId,
+            @RequestParam(required = false) Integer userId) {
+        return bookingService.getBookings(start, end, roomId, userId);
+    }
+
+    @PostMapping
+    public Booking createBooking(@RequestBody Booking booking) {
+        return bookingService.createBooking(booking);
+    }
+
+    @GetMapping("/{id}")
+    public Booking getBookingById(@PathVariable Integer id) {
+        return bookingService.getBookingById(id);
+    }
+
+    @DeleteMapping("/{id}")
+    public ResponseEntity<Void> deleteBooking(@PathVariable Integer id) {
+        try {
+            bookingService.deleteBooking(id);
+            return new ResponseEntity<>(HttpStatus.ACCEPTED);
+        } catch (RuntimeException e) {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+        }
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/models/Booking.java
similarity index 84%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/bookings/models/Booking.java
index c546d1916b1c29a10f95c97f03db34e64ffbe7d2..533ee0c7a1fa053dce449b855f1e46e08dabbe66 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/models/Booking.java
@@ -1,4 +1,4 @@
-package com.uva.roomBooking.Models;
+package com.uva.monolith.services.bookings.models;
 
 import jakarta.persistence.Basic;
 import jakarta.persistence.CascadeType;
@@ -13,6 +13,9 @@ import jakarta.persistence.ManyToOne;
 import jakarta.persistence.Table;
 import java.time.LocalDate;
 
+import com.uva.monolith.services.hotels.models.Room;
+import com.uva.monolith.services.users.models.Client;
+
 @Entity
 @Table(name = "bookings")
 public class Booking {
@@ -22,7 +25,7 @@ public class Booking {
     private int id;
     @JoinColumn(name = "user_id", referencedColumnName = "id")
     @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
-    private User userId;
+    private Client userId;
     @JoinColumn(name = "room_id", referencedColumnName = "id")
     @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
     private Room roomId;
@@ -34,7 +37,7 @@ public class Booking {
     public Booking() {
     }
 
-    public Booking(int id, User userId, Room roomID, LocalDate startDate, LocalDate endDate) {
+    public Booking(int id, Client userId, Room roomID, LocalDate startDate, LocalDate endDate) {
         this.id = id;
         this.userId = userId;
         this.roomId = roomID;
@@ -50,11 +53,11 @@ public class Booking {
         return this.id;
     }
 
-    public void setUserId(User userId) {
+    public void setUserId(Client userId) {
         this.userId = userId;
     }
 
-    public User getUserId() {
+    public Client getUserId() {
         return this.userId;
     }
 
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/repositories/BookingRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/repositories/BookingRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5ace65939b898798e6e5416fedda793388f2615
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/repositories/BookingRepository.java
@@ -0,0 +1,41 @@
+// BookingRepository.java
+package com.uva.monolith.services.bookings.repositories;
+
+import jakarta.transaction.Transactional;
+
+import java.time.LocalDate;
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import com.uva.monolith.services.bookings.models.Booking;
+
+public interface BookingRepository extends JpaRepository<Booking, Integer> {
+        @Query("SELECT b FROM Booking b WHERE b.userId.id = ?1")
+        List<Booking> findByUserId(int userId);
+
+        @Query("SELECT b FROM Booking b WHERE b.roomId.id = ?1")
+        List<Booking> findByRoomId(int roomId);
+
+        @Query("SELECT b FROM Booking b WHERE b.startDate >= ?1 AND b.endDate <= ?2")
+        List<Booking> findByDateRange(@Param("startDate") LocalDate startDate,
+                        @Param("endDate") LocalDate endDate);
+
+        @Query("SELECT b FROM Booking b WHERE b.roomId.id = ?1 AND b.startDate < ?2 AND b.endDate > ?3")
+        List<Booking> findByRoomIdAndDateRange(@Param("roomId") int roomId, @Param("startDate") LocalDate startDate,
+                        @Param("endDate") LocalDate endDate);
+
+        @Transactional
+        @Modifying
+        @Query("DELETE FROM Booking b WHERE b.id = ?1")
+        void deleteBookingById(@Param("id") Integer id);
+
+        @Transactional
+        @Modifying
+        @Query("DELETE FROM Booking b WHERE b.roomId.hotel.id = ?1")
+        void deleteAllByHotelId(int hotelId);
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/services/BookingService.java b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/services/BookingService.java
new file mode 100644
index 0000000000000000000000000000000000000000..176f49dd951630c9118b24536e8a7dd6f5a15521
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/services/BookingService.java
@@ -0,0 +1,89 @@
+package com.uva.monolith.services.bookings.services;
+
+import com.uva.monolith.services.bookings.models.Booking;
+import com.uva.monolith.services.bookings.repositories.BookingRepository;
+import com.uva.monolith.services.hotels.models.Room;
+import com.uva.monolith.services.hotels.repositories.RoomRepository;
+import com.uva.monolith.services.users.models.Client;
+import com.uva.monolith.services.users.repositories.ClientRepository;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Service
+public class BookingService {
+
+    @Autowired
+    private BookingRepository bookingRepository;
+
+    @Autowired
+    private RoomRepository roomRepository;
+
+    @Autowired
+    private ClientRepository clientRepository;
+
+    public List<Booking> getBookings(LocalDate start, LocalDate end, Integer roomId, Integer userId) {
+        List<Booking> bookings = null;
+
+        if (start != null && end != null) {
+            bookings = bookingRepository.findByDateRange(start, end);
+        }
+        if (roomId != null) {
+            if (bookings == null) {
+                bookings = bookingRepository.findByRoomId(roomId);
+            } else {
+                bookings = bookings.stream()
+                        .filter(booking -> booking.getRoomId().getId() == roomId)
+                        .toList();
+            }
+        }
+        if (userId != null) {
+            if (bookings == null) {
+                bookings = bookingRepository.findByUserId(userId);
+            } else {
+                bookings = bookings.stream()
+                        .filter(booking -> booking.getUserId().getId() == userId)
+                        .toList();
+            }
+        }
+        if (start == null && end == null && roomId == null && userId == null) {
+            bookings = bookingRepository.findAll();
+        }
+
+        return bookings;
+    }
+
+    public Booking createBooking(Booking booking) {
+        Client user = clientRepository.findById(booking.getUserId().getId())
+                .orElseThrow(() -> new RuntimeException("User not found"));
+        Room room = roomRepository.findById(booking.getRoomId().getId())
+                .orElseThrow(() -> new RuntimeException("Room not found"));
+
+        // Check availability
+        List<Booking> existingBookings = bookingRepository.findByRoomIdAndDateRange(
+                room.getId(), booking.getStartDate(), booking.getEndDate());
+
+        if (!existingBookings.isEmpty()) {
+            throw new RuntimeException("Room is not available for the selected dates");
+        }
+
+        booking.setUserId(user);
+        booking.setRoomId(room);
+        return bookingRepository.save(booking);
+    }
+
+    public Booking getBookingById(Integer id) {
+        return bookingRepository.findById(id)
+                .orElseThrow(() -> new RuntimeException("Booking not found"));
+    }
+
+    public void deleteBooking(Integer id) {
+        if (!bookingRepository.existsById(id)) {
+            throw new RuntimeException("Booking not found");
+        }
+        bookingRepository.deleteBookingById(id);
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
similarity index 87%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
index 803edc35fdcbf2b5ec7fc96972e8ee2a7777391d..5852aa794da7dcd05a8359f2756e296c829a40da 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
@@ -1,24 +1,23 @@
-package com.uva.roomBooking.Controllers;
+package com.uva.monolith.services.hotels.controllers;
 
 import java.util.List;
 import java.util.Map;
 import java.time.LocalDate;
 
-import com.uva.roomBooking.Exceptions.HotelNotFoundException;
-import com.uva.roomBooking.Exceptions.InvalidDateRangeException;
-import com.uva.roomBooking.Exceptions.InvalidRequestException;
-import com.uva.roomBooking.Models.Booking;
-import com.uva.roomBooking.Models.Hotel;
-import com.uva.roomBooking.Models.Room;
-import com.uva.roomBooking.Repositories.BookingRepository;
-import com.uva.roomBooking.Repositories.HotelRepository;
-import com.uva.roomBooking.Repositories.RoomRepository;
-
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
+import com.uva.monolith.exceptions.HotelNotFoundException;
+import com.uva.monolith.exceptions.InvalidDateRangeException;
+import com.uva.monolith.exceptions.InvalidRequestException;
+import com.uva.monolith.services.bookings.repositories.BookingRepository;
+import com.uva.monolith.services.hotels.models.Hotel;
+import com.uva.monolith.services.hotels.models.Room;
+import com.uva.monolith.services.hotels.repositories.HotelRepository;
+import com.uva.monolith.services.hotels.repositories.RoomRepository;
+
 @RestController
 @RequestMapping("hotels")
 @CrossOrigin(origins = "*")
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Address.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Address.java
similarity index 97%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Models/Address.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Address.java
index 5e51f55e710c68ac38d4cb1c5769e574b06654bf..5f31a2a530da46c00460ad6cc6151b0769c1da61 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Address.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Address.java
@@ -1,4 +1,4 @@
-package com.uva.roomBooking.Models;
+package com.uva.monolith.services.hotels.models;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java
similarity index 76%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java
index 5a23005de99c022b5fff9570e2c515fcfc75e07e..21f5cec8b44f9fae1a566b7af92964d30b654546 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java
@@ -1,9 +1,8 @@
-package com.uva.roomBooking.Models;
+package com.uva.monolith.services.hotels.models;
 
 import java.util.List;
 
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
-import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import com.uva.monolith.services.users.models.HotelManager;
 
 import jakarta.persistence.Basic;
 import jakarta.persistence.CascadeType;
@@ -13,6 +12,7 @@ import jakarta.persistence.GeneratedValue;
 import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
 import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
 import jakarta.persistence.OneToMany;
 import jakarta.persistence.OneToOne;
 import jakarta.persistence.Table;
@@ -38,14 +38,19 @@ public class Hotel {
   @OneToMany(mappedBy = "hotel", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   private List<Room> rooms;
 
+  @ManyToOne(optional = false)
+  @JoinColumn(name = "hotel_manager", referencedColumnName = "id")
+  private HotelManager hotelManager;
+
   public Hotel() {
   }
 
-  public Hotel(int id, String name, Address address, List<Room> rooms) {
+  public Hotel(int id, String name, Address address, List<Room> rooms, HotelManager hotelManager) {
     setId(id);
     setName(name);
     setAddress(address);
     setRooms(rooms);
+    setHotelManager(hotelManager);
   }
 
   public int getId() {
@@ -81,4 +86,11 @@ public class Hotel {
     rooms.forEach(room -> room.setHotel(this));
   }
 
+  public void setHotelManager(HotelManager hotelManager) {
+    this.hotelManager = hotelManager;
+  }
+
+  public HotelManager getHotelManager() {
+    return hotelManager;
+  }
 }
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Room.java
similarity index 86%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Room.java
index 639dfdb0bd3be629b16c719373fa51c9a7584898..72a6a728f729dc7b93b727606172de7cbe385ebb 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Room.java
@@ -1,10 +1,9 @@
-package com.uva.roomBooking.Models;
+package com.uva.monolith.services.hotels.models;
 
 import java.util.List;
 
-import com.fasterxml.jackson.annotation.JsonIdentityInfo;
 import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import com.uva.monolith.services.bookings.models.Booking;
 
 import jakarta.persistence.Basic;
 import jakarta.persistence.CascadeType;
@@ -36,7 +35,7 @@ public class Room {
     @Column(name = "room_number", nullable = false)
     private String roomNumber;
     @Column(name = "type", nullable = false)
-    private Tipo type;
+    private RoomType type;
     @Column(name = "available", nullable = false)
     private boolean available;
     @JsonIgnore
@@ -46,7 +45,7 @@ public class Room {
     public Room() {
     }
 
-    public Room(int id, Hotel hotelId, String roomNumber, Tipo type, boolean available, List<Booking> bookings) {
+    public Room(int id, Hotel hotelId, String roomNumber, RoomType type, boolean available, List<Booking> bookings) {
         this.id = id;
         this.hotel = hotelId;
         this.roomNumber = roomNumber;
@@ -79,11 +78,11 @@ public class Room {
         return this.roomNumber;
     }
 
-    public void setType(Tipo type) {
+    public void setType(RoomType type) {
         this.type = type;
     }
 
-    public Tipo getType() {
+    public RoomType getType() {
         return this.type;
     }
 
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/RoomType.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/RoomType.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9e82584850795afa7c7392248e3a6472ce24ac0
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/RoomType.java
@@ -0,0 +1,7 @@
+package com.uva.monolith.services.hotels.models;
+
+public enum RoomType {
+    SINGLE,
+    DOUBLE,
+    SUITE
+}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Repositories/HotelRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/HotelRepository.java
similarity index 56%
rename from java/services/hotels/src/main/java/com/uva/hotelService/Repositories/HotelRepository.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/HotelRepository.java
index ae05426286ff6fb316513da9869ff4b715040703..ad88e98985f82e695aa9ed40df30d1501990eff5 100644
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Repositories/HotelRepository.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/HotelRepository.java
@@ -1,8 +1,8 @@
-package com.uva.hotelService.Repositories;
+package com.uva.monolith.services.hotels.repositories;
 
 import org.springframework.data.jpa.repository.JpaRepository;
 
-import com.uva.hotelService.Models.Hotel;
+import com.uva.monolith.services.hotels.models.Hotel;
 
 public interface HotelRepository extends JpaRepository<Hotel, Integer> {
 
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/RoomRepository.java
similarity index 90%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/RoomRepository.java
index 3df9937f1ba7dc7c8bc0aa839a7a93ffd0baa8de..78187e4389873bb649fd451ae4cb7ed1f1f0c473 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/RoomRepository.java
@@ -1,9 +1,10 @@
-package com.uva.roomBooking.Repositories;
+package com.uva.monolith.services.hotels.repositories;
 
-import com.uva.roomBooking.Models.Room;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 
+import com.uva.monolith.services.hotels.models.Room;
+
 import java.time.LocalDate;
 import java.util.List;
 import java.util.Optional;
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java
new file mode 100644
index 0000000000000000000000000000000000000000..32b8c4d9fdfe17b26a913dd062fe19302e1bb90c
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java
@@ -0,0 +1,110 @@
+package com.uva.monolith.services.users.controllers;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.HttpClientErrorException;
+
+import com.uva.monolith.services.users.models.User;
+import com.uva.monolith.services.users.models.UserStatus;
+import com.uva.monolith.services.users.services.UserService;
+
+@RestController
+@RequestMapping("users")
+@CrossOrigin(origins = "*")
+public class UserController {
+
+  @Autowired
+  private UserService userService;
+
+  @GetMapping
+  public ResponseEntity<List<User>> getAllUsers() {
+    List<User> users = userService.getAllUsers();
+    return ResponseEntity.ok(users);
+  }
+
+  @GetMapping(params = { "email" })
+  public ResponseEntity<?> getUserByEmail(@RequestParam String email) {
+    try {
+      return ResponseEntity.ok(userService.getUserByEmail(email));
+    } catch (HttpClientErrorException e) {
+      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
+        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
+      throw e;
+    }
+  }
+
+  @PostMapping
+  public ResponseEntity<?> addUser(@RequestBody User user) {
+    userService.addUser(user);
+    return new ResponseEntity<>(HttpStatus.ACCEPTED);
+  }
+
+  @GetMapping("/{id}")
+  public ResponseEntity<?> getUserById(@PathVariable int id) {
+    return ResponseEntity.ok(userService.getUserById(id));
+  }
+
+  @PutMapping("/{id}")
+  public ResponseEntity<?> updateUserData(@PathVariable int id, @RequestBody Map<String, String> json) {
+    String name = json.get("name");
+    String email = json.get("email");
+    if (name == null || email == null) {
+      return new ResponseEntity<String>("Missing required fields", HttpStatus.BAD_REQUEST);
+    }
+    try {
+      User user = userService.updateUserData(id, name, email);
+      return new ResponseEntity<User>(user, HttpStatus.OK);
+    } catch (HttpClientErrorException e) {
+      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
+        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
+      throw e;
+    }
+  }
+
+  @PatchMapping("/{id}")
+  public ResponseEntity<?> updateUserState(@PathVariable int id, @RequestBody Map<String, String> json) {
+
+    String strStatus = json.get("status");
+    if (strStatus == null) {
+      return new ResponseEntity<String>("Missing required fields", HttpStatus.BAD_REQUEST);
+    }
+    try {
+      UserStatus userStatus = UserStatus.valueOf(strStatus);
+      return ResponseEntity.ok(userService.updateUserStatus(id, userStatus));
+    } catch (IllegalArgumentException e) {
+      return new ResponseEntity<String>("Unknown user state", HttpStatus.BAD_REQUEST);
+    } catch (HttpClientErrorException e) {
+      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
+        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
+      throw e;
+    }
+
+  }
+
+  @DeleteMapping("/{id}")
+  public ResponseEntity<?> deleteUser(@PathVariable Integer id) {
+    try {
+      return ResponseEntity.ok(userService.deleteUserById(id));
+    } catch (HttpClientErrorException e) {
+      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
+        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
+      throw e;
+    }
+  }
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/AuthResponse.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/AuthResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f334813beee8cb95caa275c66e46c9c539f2bd5
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/AuthResponse.java
@@ -0,0 +1,51 @@
+package com.uva.monolith.services.users.models;
+
+public class AuthResponse {
+
+  private int id;
+  private String username;
+  private String email;
+  private String password;
+  private UserRol rol;
+
+  public int getId() {
+    return this.id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getUsername() {
+    return this.username;
+  }
+
+  public void setUsername(String username) {
+    this.username = username;
+  }
+
+  public String getEmail() {
+    return this.email;
+  }
+
+  public void setEmail(String email) {
+    this.email = email;
+  }
+
+  public String getPassword() {
+    return this.password;
+  }
+
+  public void setPassword(String password) {
+    this.password = password;
+  }
+
+  public UserRol getRol() {
+    return this.rol;
+  }
+
+  public void setRol(UserRol rol) {
+    this.rol = rol;
+  }
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/Client.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/Client.java
new file mode 100644
index 0000000000000000000000000000000000000000..e106ecd3789a0237602e3194feacab7ddcbf4dfd
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/Client.java
@@ -0,0 +1,65 @@
+package com.uva.monolith.services.users.models;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.uva.monolith.services.bookings.models.Booking;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "user_client")
+public class Client extends User {
+
+  @Basic(optional = false)
+  @Column(nullable = false)
+  @Enumerated(EnumType.STRING)
+  private UserStatus status;
+
+  @JsonIgnore
+  @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+  private List<Booking> bookings;
+
+  public Client() {
+    super();
+    bookings = new ArrayList<>();
+    status = UserStatus.NO_BOOKINGS;
+  }
+
+  public Client(int id, String name, String email, String password, UserStatus status,
+      List<Booking> bookings) {
+    super(id, name, email, password, UserRol.CLIENT);
+    setStatus(status);
+    setBookings(bookings);
+  }
+
+  public UserStatus getStatus() {
+    if (getBookings() == null || getBookings().isEmpty())
+      return UserStatus.NO_BOOKINGS;
+    boolean activeBookings = getBookings().stream()
+        .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora
+    return activeBookings ? UserStatus.WITH_ACTIVE_BOOKINGS : UserStatus.WITH_INACTIVE_BOOKINGS;
+  }
+
+  public void setStatus(UserStatus status) {
+    this.status = status;
+  }
+
+  public List<Booking> getBookings() {
+    return this.bookings;
+  }
+
+  public void setBookings(List<Booking> bookings) {
+    this.bookings = bookings;
+  }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/HotelManager.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/HotelManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e6f4b0aafa35ab8b23d202814c1fabefdcf86ed
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/HotelManager.java
@@ -0,0 +1,38 @@
+package com.uva.monolith.services.users.models;
+
+import java.util.ArrayList;
+import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.uva.monolith.services.hotels.models.Hotel;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "hotel_manager_user")
+public class HotelManager extends User {
+
+  @JsonIgnore
+  @OneToMany(mappedBy = "hotelManager", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+  private List<Hotel> hotels;
+
+  public HotelManager() {
+    super();
+    hotels = new ArrayList<>();
+  }
+
+  public HotelManager(int id, String name, String email, String password, List<Hotel> hotels) {
+    super(id, name, email, password, UserRol.HOTEL_ADMIN);
+    setHotels(hotels);
+  }
+
+  public List<Hotel> getHotels() {
+    return this.hotels;
+  }
+
+  public void setHotels(List<Hotel> hotels) {
+    this.hotels = hotels;
+  }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/Models/User.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java
similarity index 86%
rename from java/services/auth/src/main/java/com/uva/authentication/Models/User.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java
index 9f56935cfafa594913501c6f110b6b0967ff9bad..45decd686b3972058eb920f6c2e07cd4293f1e05 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/Models/User.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java
@@ -1,6 +1,4 @@
-package com.uva.authentication.Models;
-
-import java.util.List;
+package com.uva.monolith.services.users.models;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 
@@ -52,7 +50,6 @@ public class User {
     setId(id);
     setName(name);
     setEmail(email);
-    setPassword(password);
     setRol(rol);
   }
 
@@ -81,10 +78,18 @@ public class User {
   }
 
   public String getPassword() {
-    return this.password;
+    return password;
+  }
+
+  public void setPassword(String rawPassword) {
+    this.password = rawPassword;
+  }
+
+  public UserRol getRol() {
+    return this.rol;
   }
 
-  public void setPassword(String password) {
-    this.password = password;
+  public void setRol(UserRol rol) {
+    this.rol = rol;
   }
 }
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java
new file mode 100644
index 0000000000000000000000000000000000000000..f408ba5ef9d34d96c32d3c42a6c2c51b1c6f22b1
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java
@@ -0,0 +1,5 @@
+package com.uva.monolith.services.users.models;
+
+public enum UserRol {
+  ADMIN, HOTEL_ADMIN, CLIENT
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/UserStatus.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserStatus.java
similarity index 64%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Models/UserStatus.java
rename to java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserStatus.java
index 41adce4ba6df6332286f0971b7f8e43b9126e401..362b8688260d4c13dc4a8eae205411c9d5533d79 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/UserStatus.java
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserStatus.java
@@ -1,4 +1,4 @@
-package com.uva.roomBooking.Models;
+package com.uva.monolith.services.users.models;
 
 public enum UserStatus {
   NO_BOOKINGS, WITH_ACTIVE_BOOKINGS, WITH_INACTIVE_BOOKINGS;
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/ClientRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/ClientRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c1b46fbe665075b8f817367ff14ee65cf69ff76
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/ClientRepository.java
@@ -0,0 +1,10 @@
+package com.uva.monolith.services.users.repositories;
+
+import java.util.Optional;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.uva.monolith.services.users.models.Client;
+
+public interface ClientRepository extends JpaRepository<Client, Integer> {
+  Optional<Client> findByEmail(String email);
+}
\ No newline at end of file
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/HotelManagerRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/HotelManagerRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..092a251b199fdecd80a2654fc3e6c96d1b7eb7f4
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/HotelManagerRepository.java
@@ -0,0 +1,10 @@
+package com.uva.monolith.services.users.repositories;
+
+import java.util.Optional;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.uva.monolith.services.users.models.HotelManager;
+
+public interface HotelManagerRepository extends JpaRepository<HotelManager, Integer> {
+  Optional<HotelManager> findByEmail(String email);
+}
\ No newline at end of file
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/UserRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/UserRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..e5b44c976f095719854aa8070abc843b898036fe
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/UserRepository.java
@@ -0,0 +1,11 @@
+package com.uva.monolith.services.users.repositories;
+
+import java.util.Optional;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.uva.monolith.services.users.models.User;
+
+public interface UserRepository extends JpaRepository<User, Integer> {
+  Optional<User> findByEmail(String email);
+}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/services/UserService.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/services/UserService.java
new file mode 100644
index 0000000000000000000000000000000000000000..193d736853b1f0d84ff86a4b24cfd0f8db52172d
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/monolith/services/users/services/UserService.java
@@ -0,0 +1,107 @@
+package com.uva.monolith.services.users.services;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
+
+import com.uva.monolith.services.users.models.AuthResponse;
+import com.uva.monolith.services.users.models.Client;
+import com.uva.monolith.services.users.models.User;
+import com.uva.monolith.services.users.models.UserStatus;
+import com.uva.monolith.services.users.repositories.ClientRepository;
+import com.uva.monolith.services.users.repositories.UserRepository;
+
+@Service
+public class UserService {
+
+  @Autowired
+  private UserRepository userRepository;
+
+  @Autowired
+  private ClientRepository clientRepository;
+
+  public List<User> getAllUsers() {
+    return userRepository.findAll();
+  }
+
+  private User assertUser(Optional<? extends User> opUser) {
+    return opUser.orElseThrow(() -> new HttpClientErrorException(HttpStatus.NOT_FOUND));
+  }
+
+  public User getUserById(int id) {
+    return assertUser(userRepository.findById(id));
+  }
+
+  public AuthResponse getUserByEmail(String email) {
+    User u = assertUser(userRepository.findByEmail(email));
+    AuthResponse auth = new AuthResponse();
+    BeanUtils.copyProperties(u, auth);
+    auth.setUsername(u.getName());
+    return auth;
+  }
+
+  public User addUser(User user) {
+    // Actualmente está en el servicio AUTH
+    // TODO adaptar adecuadamente
+    throw new HttpClientErrorException(HttpStatus.MOVED_PERMANENTLY, "servicio actual en http://localhost:8101/login");
+    // user.setStatus(UserStatus.NO_BOOKINGS);
+    // if (user.getRol() == null) // Rol por defecto
+    // user.setRol(UserRol.CONSUMER);
+    // // Guardamos
+    // return userRepository.save(user);
+  }
+
+  public User updateUserData(int id, String name, String email) {
+    User user = getUserById(id);
+    user.setName(name);
+    user.setEmail(email);
+    return userRepository.save(user);
+  }
+
+  public User updateUserStatus(int id, UserStatus status) {
+
+    Client user = (Client) assertUser(clientRepository.findById(id));
+
+    boolean activeBookings = user.getBookings().stream()
+        .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora
+    boolean inactiveBookings = user.getBookings().stream()
+        .anyMatch(booking -> booking.getStartDate().isBefore(LocalDate.now())); // reserva < ahora
+
+    switch (status) {
+      case NO_BOOKINGS:
+        if (!user.getBookings().isEmpty())
+          throw new IllegalArgumentException("Invalid State: The user has at least one booking");
+        break;
+      case WITH_ACTIVE_BOOKINGS:
+        if (user.getBookings().isEmpty())
+          throw new IllegalArgumentException("Invalid State: The user don't has bookings");
+        if (!activeBookings)
+          throw new IllegalArgumentException("Invalid State: The user don't has active bookings");
+        break;
+      case WITH_INACTIVE_BOOKINGS:
+        if (user.getBookings().isEmpty())
+          throw new IllegalArgumentException("Invalid State: The user don't has bookings");
+        if (!inactiveBookings)
+          throw new IllegalArgumentException("Invalid State: The user don't has inactive bookings");
+        break;
+      default:
+        break;
+    }
+    user.setStatus(status);
+    return userRepository.save(user);
+  }
+
+  public User deleteUserById(int id) {
+    User user = getUserById(id);
+    // TODO eliminar reservas de usuario ahora mismo no por el modo cascada pero a
+    // futuro sí, después de la disgregación en microservicios
+    userRepository.deleteById(id);
+    return user;
+  }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java
deleted file mode 100644
index 5baa50358b36dfffd3184fd0e7e46a9177b2ef55..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// BookingController.java
-package com.uva.roomBooking.Controllers;
-
-import com.uva.roomBooking.Models.Booking;
-import com.uva.roomBooking.Models.Room;
-import com.uva.roomBooking.Models.User;
-import com.uva.roomBooking.Repositories.BookingRepository;
-import com.uva.roomBooking.Repositories.RoomRepository;
-import com.uva.roomBooking.Repositories.UserRepository;
-
-import jakarta.transaction.Transactional;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.HttpStatusCode;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/bookings")
-@CrossOrigin(origins = "*")
-public class BookingController {
-
-    private final BookingRepository bookingRepository;
-    private final UserRepository userRepository;
-    private final RoomRepository roomRepository;
-
-    public BookingController(BookingRepository bookingRepository, UserRepository userRepository,
-            RoomRepository roomRepository) {
-        this.bookingRepository = bookingRepository;
-        this.userRepository = userRepository;
-        this.roomRepository = roomRepository;
-    }
-
-    @GetMapping
-    public List<Booking> getAllBookings() {
-        return bookingRepository.findAll();
-    }
-
-    @PostMapping
-    public Booking createBooking(@RequestBody Booking booking) {
-        User user = userRepository.findById(booking.getUserId().getId())
-                .orElseThrow(() -> new RuntimeException("User not found"));
-        Room room = roomRepository.findById(booking.getRoomId().getId())
-                .orElseThrow(() -> new RuntimeException("Room not found"));
-
-        // Verificar disponibilidad
-        List<Booking> existingBookings = bookingRepository.findByRoomIdAndDateRange(
-                room.getId(), booking.getStartDate(), booking.getEndDate());
-
-        if (!existingBookings.isEmpty()) {
-            throw new RuntimeException("Room is not available for the selected dates");
-        }
-
-        booking.setUserId(user);
-        booking.setRoomId(room);
-        return bookingRepository.save(booking);
-    }
-
-    @GetMapping("/{id}")
-    public Booking getBookingById(@PathVariable Integer id) {
-        return bookingRepository.findById(id)
-                .orElseThrow(() -> new RuntimeException("Booking not found"));
-    }
-
-    @DeleteMapping("/{id}")
-    @Transactional
-    public ResponseEntity<Void> deleteBooking(@PathVariable Integer id) {
-        try {
-            if (!bookingRepository.existsById(id))
-                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
-
-            bookingRepository.deleteBookingById(id);
-            return new ResponseEntity<>(HttpStatus.ACCEPTED);
-        } catch (Exception e) {
-            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
-        }
-    }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/UserController.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/UserController.java
deleted file mode 100644
index a0e6397b9cabc191f7d5d24ecde162e8da6b2f14..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/UserController.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package com.uva.roomBooking.Controllers;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PatchMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import com.uva.roomBooking.Models.UserStatus;
-import com.uva.roomBooking.Models.Booking;
-import com.uva.roomBooking.Models.User;
-import com.uva.roomBooking.Repositories.UserRepository;
-
-@RestController
-@RequestMapping("users")
-@CrossOrigin(origins = "*")
-public class UserController {
-  private final UserRepository userRepository;
-
-  public UserController(UserRepository userRepository) {
-    this.userRepository = userRepository;
-  }
-
-  @GetMapping
-  public List<User> getAllUsers() {
-    return userRepository.findAll();
-  }
-
-  @PostMapping
-  public User addUser(@RequestBody User user) {
-    // TODO revisar como se desea manejar estado por defecto
-    user.setStatus(UserStatus.NO_BOOKINGS);
-    // Aunque se asegure a lo mejor no es la forma de manejo esperada
-    return userRepository.save(user);
-  }
-
-  @GetMapping("/{id}")
-  public User getUserById(@PathVariable int id) {
-    return userRepository.findById(id).orElseThrow();
-  }
-
-  @PutMapping("/{id}")
-  public User updateUserData(@PathVariable int id, @RequestBody Map<String, String> json) {
-    User target = userRepository.findById(id).orElseThrow();
-    if (!json.containsKey("name") || !json.containsKey("email")) {
-      // TODO cambiar manejo
-      throw new RuntimeException("Missing required fields");
-    }
-    target.setName(json.get("name"));
-    target.setEmail(json.get("email"));
-    return userRepository.save(target);
-  }
-
-  @PatchMapping("/{id}")
-  public User updateUserState(@PathVariable int id, @RequestBody Map<String, String> json) {
-    User target = userRepository.findById(id).orElseThrow();
-    String strStatus = json.get("status");
-    if (strStatus == null) {
-      // TODO cambiar manejo
-      throw new RuntimeException("Missing required fields");
-    }
-    UserStatus userStatus = UserStatus.valueOf(strStatus);
-
-    boolean activeBookings = target.getBookings().stream()
-        .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora
-    boolean inactiveBookings = target.getBookings().stream()
-        .anyMatch(booking -> booking.getStartDate().isBefore(LocalDate.now())); // reserva < ahora
-
-    switch (userStatus) {
-      // TODO Buscar como validar las (in)active bookings
-      case NO_BOOKINGS:
-        if (!target.getBookings().isEmpty())
-          throw new IllegalArgumentException("Invalid State: The user has at least one booking");
-        break;
-      case WITH_ACTIVE_BOOKINGS:
-        if (target.getBookings().isEmpty())
-          throw new IllegalArgumentException("Invalid State: The user don't has bookings");
-        if (!activeBookings)
-          throw new IllegalArgumentException("Invalid State: The user don't has active bookings");
-        break;
-      case WITH_INACTIVE_BOOKINGS:
-        if (target.getBookings().isEmpty())
-          throw new IllegalArgumentException("Invalid State: The user don't has bookings");
-        if (!inactiveBookings)
-          throw new IllegalArgumentException("Invalid State: The user don't has inactive bookings");
-        break;
-      default:
-        break;
-    }
-    target.setStatus(userStatus);
-    return userRepository.save(target);
-  }
-
-  @DeleteMapping("/{id}")
-  public User deleteUser(@PathVariable Integer id) {
-    User target;
-    if ((target = userRepository.findById(id).orElseThrow()) != null) {
-      userRepository.deleteById(id);
-    }
-    return target;
-  }
-
-  @GetMapping("/{id}/bookings")
-  public List<Booking> getUserBookingsById(@PathVariable int id) {
-    User user = userRepository.findById(id).orElseThrow();
-    return user.getBookings();
-  }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java
deleted file mode 100644
index 03b21e27ffa7e4e921cc9801187911d9f1be6a52..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.uva.roomBooking.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-@ControllerAdvice
-public class GlobalExceptionHandler {
-
-    @ExceptionHandler(HotelNotFoundException.class)
-    public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
-    }
-
-    @ExceptionHandler(InvalidRequestException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidRequest(InvalidRequestException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    @ExceptionHandler(InvalidDateRangeException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidDateRange(InvalidDateRangeException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    @ExceptionHandler(Exception.class)
-    public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", "An unexpected error occurred: " + ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
-    }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java
deleted file mode 100644
index 3d47f5efad71b6fbf3b3f5912493c9c0af1ca412..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.roomBooking.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.NOT_FOUND)  // Devuelve un 404 cuando se lanza la excepción
-public class HotelNotFoundException extends RuntimeException {
-    public HotelNotFoundException(int id) {
-        super("Hotel not found with id: " + id);
-    }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java
deleted file mode 100644
index 17a8420453ef402411b61b965d001560a4dd51ce..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.uva.roomBooking.Exceptions;
-
-public class InvalidDateRangeException extends RuntimeException {
-    public InvalidDateRangeException(String message) {
-        super(message);
-    }
-}
-
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Tipo.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Tipo.java
deleted file mode 100644
index e1a48b53450e1f87ae070b1bf70bd6a9afc1ea34..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Tipo.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.uva.roomBooking.Models;
-
-public enum Tipo {
-    SINGLE, 
-    DOUBLE, 
-    SUITE
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java
deleted file mode 100644
index c5373df6edc5e936d9c94f794ae36d3289d173d5..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.uva.roomBooking.Models;
-
-import java.util.List;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
-import jakarta.persistence.Basic;
-import jakarta.persistence.CascadeType;
-import jakarta.persistence.Entity;
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.OneToMany;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "users")
-public class User {
-  @Id
-  @GeneratedValue(strategy = GenerationType.IDENTITY)
-  @Basic(optional = false)
-  private int id;
-
-  @Basic(optional = false)
-  private String name;
-
-  @Basic(optional = false)
-  private String email;
-
-  @Basic(optional = false)
-  @Enumerated(EnumType.STRING)
-  private UserStatus status = UserStatus.NO_BOOKINGS;
-
-  @JsonIgnore
-  @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
-  private List<Booking> bookings;
-
-  public User() {
-  }
-
-  public User(int id, String name, String email, UserStatus status, List<Booking> bookings) {
-    setId(id);
-    setEmail(email);
-    setStatus(status);
-    setBookings(bookings);
-  }
-
-  public int getId() {
-    return this.id;
-  }
-
-  public void setId(int id) {
-    this.id = id;
-  }
-
-  public String getName() {
-    return this.name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public String getEmail() {
-    return this.email;
-  }
-
-  public void setEmail(String email) {
-    this.email = email;
-  }
-
-  public UserStatus getStatus() {
-    return this.status;
-  }
-
-  public void setStatus(UserStatus status) {
-    this.status = status;
-  }
-
-  public List<Booking> getBookings() {
-    return this.bookings;
-  }
-
-  public void setBookings(List<Booking> bookings) {
-    this.bookings = bookings;
-  }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/BookingRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/BookingRepository.java
deleted file mode 100644
index 16c860a30fd168d4e03018ef02466dcd5adb7f99..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/BookingRepository.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// BookingRepository.java
-package com.uva.roomBooking.Repositories;
-
-import com.uva.roomBooking.Models.Booking;
-
-import jakarta.transaction.Transactional;
-
-import java.time.LocalDate;
-import java.util.List;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-
-public interface BookingRepository extends JpaRepository<Booking, Integer> {
-
-    @Query("SELECT b FROM Booking b WHERE b.roomId.id = ?1 AND b.startDate < ?2 AND b.endDate > ?3")
-    List<Booking> findByRoomIdAndDateRange(@Param("roomId") int roomId, @Param("startDate") LocalDate startDate,
-            @Param("endDate") LocalDate endDate);
-
-    @Transactional
-    @Modifying
-    @Query("DELETE FROM Booking b WHERE b.id = ?1")
-    void deleteBookingById(@Param("id") Integer id);
-
-    @Transactional
-    @Modifying
-    @Query("DELETE FROM Booking b WHERE b.roomId.hotel.id = ?1")
-    void deleteAllByHotelId(int hotelId);
-
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/HotelRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/HotelRepository.java
deleted file mode 100644
index 290f129a7be376279300062d4bf3d7a614abefcc..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/HotelRepository.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.uva.roomBooking.Repositories;
-
-import com.uva.roomBooking.Models.Hotel;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface HotelRepository extends JpaRepository<Hotel, Integer> {
-
-}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/UserRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/UserRepository.java
deleted file mode 100644
index 5f02f6d4a3b2147d181b8db36736d85ccfd884b5..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/UserRepository.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.uva.roomBooking.Repositories;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import com.uva.roomBooking.Models.User;
-
-public interface UserRepository extends JpaRepository<User, Integer> {
-
-}
diff --git a/java/roomBooking/src/main/resources/application.properties b/java/roomBooking/src/main/resources/application.properties
index 563d4ad07ad10e7fb52bb3defcc3b736d889447b..e9a1304c8364b789ce008c161df0f98daf1238a9 100644
--- a/java/roomBooking/src/main/resources/application.properties
+++ b/java/roomBooking/src/main/resources/application.properties
@@ -7,4 +7,5 @@ spring.datasource.password=password
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
 # Usar esto para alternar entre las exposición del room repository ya que no es necesario su uso pero por defecto, al no cubrir su ruta, se expone
-# spring.data.rest.base-path=false
\ No newline at end of file
+# spring.data.rest.base-path=false
+external.services.auth.host=localhost:8101
\ No newline at end of file
diff --git a/java/services/auth/pom.xml b/java/services/auth/pom.xml
index 9cbd96d71de023623d5eeb168a533f99b9dc8ccc..19b9923d7ad2a8b056e02681630234471de0a9d3 100644
--- a/java/services/auth/pom.xml
+++ b/java/services/auth/pom.xml
@@ -49,20 +49,26 @@
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+		<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
+		<dependency>
+			<groupId>org.springframework.security</groupId>
+			<artifactId>spring-security-core</artifactId>
+			<version>6.4.1</version>
+		</dependency>
 		<dependency>
 			<groupId>io.jsonwebtoken</groupId>
 			<artifactId>jjwt-api</artifactId>
-			<version>0.11.2</version>
+			<version>0.11.5</version>
 		</dependency>
 		<dependency>
 			<groupId>io.jsonwebtoken</groupId>
 			<artifactId>jjwt-impl</artifactId>
-			<version>0.11.2</version>
+			<version>0.11.5</version>
 		</dependency>
 		<dependency>
 			<groupId>io.jsonwebtoken</groupId>
 			<artifactId>jjwt-jackson</artifactId>
-			<version>0.11.2</version>
+			<version>0.11.5</version>
 		</dependency>
 	</dependencies>
 
@@ -75,4 +81,4 @@
 		</plugins>
 	</build>
 
-</project>
+</project>
\ No newline at end of file
diff --git a/java/services/auth/src/main/java/com/uva/authentication/Controllers/AuthenticationController.java b/java/services/auth/src/main/java/com/uva/authentication/Controllers/AuthenticationController.java
deleted file mode 100644
index f650865625d8d7364c2b0718598351606ad546ce..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/Controllers/AuthenticationController.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.uva.authentication.Controllers;
-
-import com.uva.authentication.Models.User;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.client.RestTemplate;
-
-import java.util.Date;
-
-@RestController
-@RequestMapping("/auth")
-public class AuthenticationController {
-
-    @Autowired
-    private RestTemplate restTemplate;  // Usamos RestTemplate para acceder al microservicio de usuarios
-
-    private final String USER_SERVICE_URL = "http://user-service/users";  // URL del microservicio de usuarios
-
-    // Clave secreta para firmar el token JWT
-    private final String SECRET_KEY = "your-secret-key";  // Cambia esto por una clave secreta segura
-
-    @PostMapping("/login")
-    public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
-        // Hacemos una llamada al microservicio de usuarios para obtener el usuario por correo
-        ResponseEntity<User> userResponse = restTemplate.getForEntity(
-                USER_SERVICE_URL + "/{email}",
-                User.class,
-                loginRequest.getEmail()
-        );
-
-        // Verificamos si el usuario existe
-        if (userResponse.getStatusCode().is2xxSuccessful()) {
-            User user = userResponse.getBody();
-            // Verificamos que la contraseña coincida (esto debería hacerse de forma segura en un servicio real)
-            if (user != null && user.getPassword().equals(loginRequest.getPassword())) {
-                // Generamos el token JWT si la autenticación es correcta
-                String token = generateToken(user.getName(), user.getEmail());
-                return ResponseEntity.ok(new AuthResponse(token));
-            }
-        }
-
-        // Si el usuario no existe o la contraseña es incorrecta
-        return ResponseEntity.status(401).body("Invalid email or password");
-    }
-
-    // Método para generar el token JWT
-    private String generateToken(String name, String email) {
-        return Jwts.builder()
-                .setSubject(name)
-                .claim("email", email)  // Añadimos el correo como parte del payload
-                .setIssuedAt(new Date())  // Fecha de emisión
-                .setExpiration(new Date(System.currentTimeMillis() + 3600000))  // Expira en 1 hora
-                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)  // Firma con la clave secreta
-                .compact();
-    }
-
-    public static class LoginRequest {
-        private String email;
-        private String password;
-
-        // Getters and setters
-        public String getEmail() {
-            return email;
-        }
-
-        public void setEmail(String email) {
-            this.email = email;
-        }
-
-        public String getPassword() {
-            return password;
-        }
-
-        public void setPassword(String password) {
-            this.password = password;
-        }
-    }
-
-    public static class AuthResponse {
-        private String token;
-
-        public AuthResponse(String token) {
-            this.token = token;
-        }
-
-        // Getter
-        public String getToken() {
-            return token;
-        }
-    }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/GlobalExceptionHandler.java b/java/services/auth/src/main/java/com/uva/authentication/Exceptions/GlobalExceptionHandler.java
deleted file mode 100644
index f8c8057c9c856a01ee309437de85576d34b0ff13..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.uva.authentication.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-@ControllerAdvice
-public class GlobalExceptionHandler {
-
-    @ExceptionHandler(HotelNotFoundException.class)
-    public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
-    }
-
-    @ExceptionHandler(InvalidRequestException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidRequest(InvalidRequestException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    @ExceptionHandler(InvalidDateRangeException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidDateRange(InvalidDateRangeException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    @ExceptionHandler(Exception.class)
-    public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", "An unexpected error occurred: " + ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
-    }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/HotelNotFoundException.java b/java/services/auth/src/main/java/com/uva/authentication/Exceptions/HotelNotFoundException.java
deleted file mode 100644
index 13270b07b214169a995fa980ddbd72cd45aa728f..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/HotelNotFoundException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.authentication.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.NOT_FOUND)  // Devuelve un 404 cuando se lanza la excepción
-public class HotelNotFoundException extends RuntimeException {
-    public HotelNotFoundException(int id) {
-        super("Hotel not found with id: " + id);
-    }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/InvalidDateRangeException.java b/java/services/auth/src/main/java/com/uva/authentication/Exceptions/InvalidDateRangeException.java
deleted file mode 100644
index 699ddc9124f4aea097659ad8dac1d6d4321654b8..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/InvalidDateRangeException.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.uva.authentication.Exceptions;
-
-public class InvalidDateRangeException extends RuntimeException {
-    public InvalidDateRangeException(String message) {
-        super(message);
-    }
-}
-
diff --git a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/InvalidRequestException.java b/java/services/auth/src/main/java/com/uva/authentication/Exceptions/InvalidRequestException.java
deleted file mode 100644
index 20bd4d00df753bad8b6bfa53ca5f2fc1b74284b0..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/Exceptions/InvalidRequestException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.authentication.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class InvalidRequestException extends RuntimeException {
-    public InvalidRequestException(String message) {
-        super(message);
-    }
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/Models/UserStatus.java b/java/services/auth/src/main/java/com/uva/authentication/Models/UserStatus.java
deleted file mode 100644
index 7d37403ba4c02364414e2cdf99cd4f9db269aa3f..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/Models/UserStatus.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.uva.authentication.Models;
-
-public enum UserStatus {
-  NO_BOOKINGS, WITH_ACTIVE_BOOKINGS, WITH_INACTIVE_BOOKINGS;
-}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java b/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4aa44728a593f54275339d99c9e603b20b802e9
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java
@@ -0,0 +1,74 @@
+// TODO eliminar si realmente no necesitamos comunicar un servicio con otro
+package com.uva.authentication.api;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.RestTemplate;
+
+import com.uva.authentication.models.RegisterRequest;
+import com.uva.authentication.models.remote.User;
+import com.uva.authentication.models.remote.UserRol;
+import com.uva.authentication.utils.JwtUtil;
+
+@Component
+public class UserAPI {
+
+  @Autowired
+  private RestTemplate restTemplate;
+
+  @Value("${external.services.users.baseurl}")
+  private String USER_API_URL;
+
+  @Autowired
+  private JwtUtil jwtUtil;
+
+  private String token;
+  private final User USER = new User(-1, "admin", null, null, UserRol.ADMIN);
+
+  private String getAccessToken() {
+    if (token == null || token.isEmpty() || jwtUtil.isTokenValid(token, USER)) {
+      token = jwtUtil.generateToken(USER);
+    }
+    return token;
+  }
+
+  public User getUserByEmail(String email) {
+
+    // Implementación para acceder con autentificación
+    // String token = getAccessToken();
+    // HttpHeaders headers = new HttpHeaders();
+    // headers.set("Authorization", "Bearer " + token);
+    // HttpEntity<Void> entity = new HttpEntity<>(headers);
+
+    String url = USER_API_URL + "?email={" + email + "}";
+    try {
+      ResponseEntity<User> userResponse = restTemplate.getForEntity(url, User.class, email);
+      // restTemplate.exchange(url, HttpMethod.GET, entity, User.class);
+      return userResponse.getBody();
+    } catch (HttpClientErrorException e) {
+      if (e.getStatusCode() != HttpStatus.NOT_FOUND)
+        throw e;
+      return null;
+    }
+  }
+
+  public User registerUser(RegisterRequest registerRequest) {
+
+    String token = getAccessToken();
+    HttpHeaders headers = new HttpHeaders();
+    headers.set("Authorization", "Bearer " + token);
+
+    String url = USER_API_URL;
+    ResponseEntity<User> userResponse = restTemplate.postForEntity(url, registerRequest, User.class, headers);
+    if (!userResponse.getStatusCode().is2xxSuccessful())
+      throw new RuntimeException("Failed to register user");
+
+    return userResponse.getBody();
+  }
+
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java b/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java
new file mode 100644
index 0000000000000000000000000000000000000000..23625a6e7824cadda471d847ecede0b94cb565da
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/controllers/AuthController.java
@@ -0,0 +1,50 @@
+package com.uva.authentication.controllers;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.HttpClientErrorException;
+import com.uva.authentication.models.*;
+import com.uva.authentication.services.AuthService;
+
+@RestController
+@CrossOrigin(origins = "*")
+public class AuthController {
+
+    @Autowired
+    private AuthService authService;
+
+    @PostMapping("/login")
+    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
+        try {
+            String token = authService.login(loginRequest);
+            return ResponseEntity.ok(new JwtAuthResponse(token));
+        } catch (HttpClientErrorException e) {
+            if (e.getStatusCode() == HttpStatus.FORBIDDEN) {
+                return new ResponseEntity<String>(e.getMessage(), HttpStatus.FORBIDDEN);
+            }
+        }
+        return new ResponseEntity<String>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+    }
+
+    @PostMapping("/register")
+    public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest) {
+        try {
+            LoginRequest loginRequest = new LoginRequest();
+            loginRequest.setEmail(registerRequest.getEmail());
+            loginRequest.setPassword(registerRequest.getPassword());
+
+            authService.register(registerRequest);
+            return login(loginRequest);
+        } catch (HttpClientErrorException e) {
+            if (e.getStatusCode() == HttpStatus.CONFLICT) {
+                return new ResponseEntity<String>(e.getMessage(), HttpStatus.CONFLICT);
+            }
+            e.fillInStackTrace();
+        }
+
+        return new ResponseEntity<String>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+    }
+
+}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/GlobalExceptionHandler.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/GlobalExceptionHandler.java
similarity index 76%
rename from java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/GlobalExceptionHandler.java
rename to java/services/auth/src/main/java/com/uva/authentication/exceptions/GlobalExceptionHandler.java
index 29c475c6cb4f50505fd4ea798423fdbabc74d502..6d4b8d58dbb5560de50b5b2149cbe3f181687446 100644
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/GlobalExceptionHandler.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/exceptions/GlobalExceptionHandler.java
@@ -1,4 +1,4 @@
-package com.uva.hotelService.Exceptions;
+package com.uva.authentication.exceptions;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -39,12 +39,13 @@ public class GlobalExceptionHandler {
         return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
     }
 
-    @ExceptionHandler(Exception.class)
-    public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", "An unexpected error occurred: " + ex.getMessage());
+    // @ExceptionHandler(Exception.class)
+    // public ResponseEntity<Map<String, Object>> handleGeneralException(Exception
+    // ex) {
+    // Map<String, Object> body = new HashMap<>();
+    // body.put("timestamp", LocalDateTime.now());
+    // body.put("message", "An unexpected error occurred: " + ex.getMessage());
 
-        return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
-    }
+    // return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
+    // }
 }
diff --git a/java/services/users/src/main/java/com/uva/users/Exceptions/HotelNotFoundException.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/HotelNotFoundException.java
similarity index 67%
rename from java/services/users/src/main/java/com/uva/users/Exceptions/HotelNotFoundException.java
rename to java/services/auth/src/main/java/com/uva/authentication/exceptions/HotelNotFoundException.java
index ef8366dc04e7c03a6758a60c8133b606b114d80b..c642139b421a5cf864218fa2d0063f955335c5b7 100644
--- a/java/services/users/src/main/java/com/uva/users/Exceptions/HotelNotFoundException.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/exceptions/HotelNotFoundException.java
@@ -1,9 +1,9 @@
-package com.uva.users.Exceptions;
+package com.uva.authentication.exceptions;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.ResponseStatus;
 
-@ResponseStatus(HttpStatus.NOT_FOUND)  // Devuelve un 404 cuando se lanza la excepción
+@ResponseStatus(HttpStatus.NOT_FOUND) // Devuelve un 404 cuando se lanza la excepción
 public class HotelNotFoundException extends RuntimeException {
     public HotelNotFoundException(int id) {
         super("Hotel not found with id: " + id);
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/InvalidDateRangeException.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidDateRangeException.java
similarity index 78%
rename from java/services/bookings/src/main/java/com/uva/bookings/Exceptions/InvalidDateRangeException.java
rename to java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidDateRangeException.java
index adca056e50cc8a5a27e06510b4eefe0ebcfb3207..c3dc917fb03495480007365b117e185521cf7bf2 100644
--- a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/InvalidDateRangeException.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidDateRangeException.java
@@ -1,8 +1,7 @@
-package com.uva.bookings.Exceptions;
+package com.uva.authentication.exceptions;
 
 public class InvalidDateRangeException extends RuntimeException {
     public InvalidDateRangeException(String message) {
         super(message);
     }
 }
-
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java b/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidRequestException.java
similarity index 87%
rename from java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java
rename to java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidRequestException.java
index a8433b6f620da742dab87dae96a2e0f0193709ff..499a320e58ecd7576cbfff39101db14395f0edbe 100644
--- a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidRequestException.java
@@ -1,4 +1,4 @@
-package com.uva.roomBooking.Exceptions;
+package com.uva.authentication.exceptions;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.ResponseStatus;
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java b/java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..e943a69108d5da38d4956509242935a6e4eb659e
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java
@@ -0,0 +1,53 @@
+package com.uva.authentication.models;
+
+import com.uva.authentication.models.remote.UserRol;
+
+public class AuthResponse {
+
+  private int id;
+  private String username;
+  private String email;
+  private String password;
+  private UserRol rol;
+
+  public int getId() {
+    return this.id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getUsername() {
+    return this.username;
+  }
+
+  public void setUsername(String username) {
+    this.username = username;
+  }
+
+  public String getEmail() {
+    return this.email;
+  }
+
+  public void setEmail(String email) {
+    this.email = email;
+  }
+
+  public String getPassword() {
+    return this.password;
+  }
+
+  public void setPassword(String password) {
+    this.password = password;
+  }
+
+  public UserRol getRol() {
+    return this.rol;
+  }
+
+  public void setRol(UserRol rol) {
+    this.rol = rol;
+  }
+
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuthResponse.java b/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuthResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9566954c35ce71864881e320843e270a998b9da
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuthResponse.java
@@ -0,0 +1,14 @@
+package com.uva.authentication.models;
+
+public class JwtAuthResponse {
+  private String token;
+
+  public JwtAuthResponse(String token) {
+    this.token = token;
+  }
+
+  // Getter
+  public String getToken() {
+    return token;
+  }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/LoginRequest.java b/java/services/auth/src/main/java/com/uva/authentication/models/LoginRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d829de96fd9a45ed458976f03107f38e8933e797
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/LoginRequest.java
@@ -0,0 +1,26 @@
+package com.uva.authentication.models;
+
+import java.util.Objects;
+
+public class LoginRequest {
+  private String email;
+  private String password = String.valueOf(Objects.hashCode("hi"));
+
+  // Getters and setters
+  public String getEmail() {
+    return email;
+  }
+
+  public void setEmail(String email) {
+    this.email = email;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public void setPassword(String password) {
+    this.password = password;
+  }
+
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/RegisterRequest.java b/java/services/auth/src/main/java/com/uva/authentication/models/RegisterRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b3c98e8e71e7ff14f2bb90c9f1b4e0cecf7e8ae7
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/RegisterRequest.java
@@ -0,0 +1,25 @@
+package com.uva.authentication.models;
+
+import com.uva.authentication.models.remote.UserRol;
+
+public class RegisterRequest extends LoginRequest {
+  private UserRol rol;
+  private String name;
+
+  public UserRol getRol() {
+    return this.rol;
+  }
+
+  public void setRol(UserRol rol) {
+    this.rol = rol;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/remote/Client.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/Client.java
new file mode 100644
index 0000000000000000000000000000000000000000..69bb23c34c2f3c47f53365fab16abfda76871c60
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/Client.java
@@ -0,0 +1,52 @@
+package com.uva.authentication.models.remote;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "user_client")
+public class Client extends User {
+
+  @Basic(optional = false)
+  @Column(nullable = false)
+  @Enumerated(EnumType.STRING)
+  private UserStatus status;
+
+  // @JsonIgnore
+  // @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade =
+  // CascadeType.ALL)
+  // private List<?> bookings;
+
+  public Client() {
+    super();
+    // bookings = new ArrayList<>();
+    status = UserStatus.NO_BOOKINGS;
+  }
+
+  public Client(int id, String name, String email, String password, UserStatus status) {
+    // , List<?> bookings) {
+    super(id, name, email, password, UserRol.CLIENT);
+    setStatus(status);
+    // setBookings(bookings);
+  }
+
+  public UserStatus getStatus() {
+    return this.status;
+  }
+
+  public void setStatus(UserStatus status) {
+    this.status = status;
+  }
+
+  // public List<?> getBookings() {
+  // return this.bookings;
+  // }
+
+  // public void setBookings(List<?> bookings) {
+  // this.bookings = bookings;
+  // }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/remote/HotelManager.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/HotelManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..584a33677a7a846d2896dc300c811b9759c9168f
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/HotelManager.java
@@ -0,0 +1,33 @@
+package com.uva.authentication.models.remote;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "hotel_manager_user")
+public class HotelManager extends User {
+
+  // TODO tener en cuenta que esto hay que tener un control adecuado
+  // @JsonIgnore
+  // @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade =
+  // CascadeType.ALL)
+  // private List<?> hotels;
+
+  public HotelManager() {
+    super();
+    // hotels = new ArrayList<>();
+  }
+
+  public HotelManager(int id, String name, String email, String password) { // , List<?> hotels) {
+    super(id, name, email, password, UserRol.HOTEL_ADMIN);
+    // setHotels(hotels);
+  }
+
+  // public List<?> getHotels() {
+  // return this.hotels;
+  // }
+
+  // public void setHotels(List<?> hotels) {
+  // this.hotels = hotels;
+  // }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserRol.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserRol.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe4d90dd1dd595f4c09ec699b452910352b406d5
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserRol.java
@@ -0,0 +1,5 @@
+package com.uva.authentication.models.remote;
+
+public enum UserRol {
+  ADMIN, HOTEL_ADMIN, CLIENT
+}
diff --git a/java/services/users/src/main/java/com/uva/users/Models/UserStatus.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserStatus.java
similarity index 65%
rename from java/services/users/src/main/java/com/uva/users/Models/UserStatus.java
rename to java/services/auth/src/main/java/com/uva/authentication/models/remote/UserStatus.java
index 95ebb033127fd89a1af9685deded8c842786645d..5dd62bc5c75271eafa9daa58ad332aa8ad56d413 100644
--- a/java/services/users/src/main/java/com/uva/users/Models/UserStatus.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/UserStatus.java
@@ -1,4 +1,4 @@
-package com.uva.users.Models;
+package com.uva.authentication.models.remote;
 
 public enum UserStatus {
   NO_BOOKINGS, WITH_ACTIVE_BOOKINGS, WITH_INACTIVE_BOOKINGS;
diff --git a/java/services/auth/src/main/java/com/uva/authentication/repositories/ClientRepository.java b/java/services/auth/src/main/java/com/uva/authentication/repositories/ClientRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..3019f8145452aa3f8e1347ab9f9296b2ffeea71a
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/repositories/ClientRepository.java
@@ -0,0 +1,11 @@
+package com.uva.authentication.repositories;
+
+import java.util.Optional;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.uva.authentication.models.remote.Client;
+import com.uva.authentication.models.remote.User;
+
+public interface ClientRepository extends JpaRepository<User, Integer> {
+  Optional<Client> findByEmail(String email);
+}
\ No newline at end of file
diff --git a/java/services/auth/src/main/java/com/uva/authentication/repositories/HotelManagerRepository.java b/java/services/auth/src/main/java/com/uva/authentication/repositories/HotelManagerRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..2d50305d0fc98a1ca2fdfb55cf4dd8de4fd4b659
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/repositories/HotelManagerRepository.java
@@ -0,0 +1,11 @@
+package com.uva.authentication.repositories;
+
+import java.util.Optional;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.uva.authentication.models.remote.HotelManager;
+import com.uva.authentication.models.remote.User;
+
+public interface HotelManagerRepository extends JpaRepository<User, Integer> {
+  Optional<HotelManager> findByEmail(String email);
+}
\ No newline at end of file
diff --git a/java/services/users/src/main/java/com/uva/users/Repositories/UserRepository.java b/java/services/auth/src/main/java/com/uva/authentication/repositories/UserRepository.java
similarity index 53%
rename from java/services/users/src/main/java/com/uva/users/Repositories/UserRepository.java
rename to java/services/auth/src/main/java/com/uva/authentication/repositories/UserRepository.java
index 730510d96586d62c9596fae8b711c06840cd2ff9..65f98edd7f2d0700de933199ae54c484eb8c71a3 100644
--- a/java/services/users/src/main/java/com/uva/users/Repositories/UserRepository.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/repositories/UserRepository.java
@@ -1,11 +1,10 @@
-package com.uva.users.Repositories;
+package com.uva.authentication.repositories;
 
 import java.util.Optional;
-
 import org.springframework.data.jpa.repository.JpaRepository;
 
-import com.uva.users.Models.User;
+import com.uva.authentication.models.remote.User;
 
 public interface UserRepository extends JpaRepository<User, Integer> {
-    Optional<User> findByEmail(String email);
-}
+  Optional<User> findByEmail(String email);
+}
\ No newline at end of file
diff --git a/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java b/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e392a7bb693ab2db0b176eae4dc69aafc44db6b3
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/services/AuthService.java
@@ -0,0 +1,98 @@
+package com.uva.authentication.services;
+
+import java.util.Optional;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpClientErrorException;
+
+import com.uva.authentication.models.LoginRequest;
+import com.uva.authentication.models.RegisterRequest;
+import com.uva.authentication.models.remote.Client;
+import com.uva.authentication.models.remote.HotelManager;
+import com.uva.authentication.models.remote.User;
+import com.uva.authentication.models.remote.UserRol;
+import com.uva.authentication.repositories.ClientRepository;
+import com.uva.authentication.repositories.HotelManagerRepository;
+import com.uva.authentication.repositories.UserRepository;
+import com.uva.authentication.utils.JwtUtil;
+import com.uva.authentication.utils.SecurityUtils;
+
+@Service
+public class AuthService {
+
+  @Autowired
+  private JwtUtil jwtUtil;
+
+  @Autowired
+  private HotelManagerRepository hotelManagerRepository;
+
+  @Autowired
+  private ClientRepository clientRepository;
+
+  @Autowired
+  private UserRepository userRepository;
+
+  private boolean authenticateUser(LoginRequest request, User user) {
+    if (user == null)
+      return false;
+    return SecurityUtils.checkPassword(request.getPassword(), user.getPassword());
+  }
+
+  public String login(LoginRequest loginRequest) {
+    User user = userRepository.findByEmail(loginRequest.getEmail())
+        .orElseThrow(() -> new HttpClientErrorException(HttpStatus.FORBIDDEN,
+            "Invalid credentials"));
+
+    if (!authenticateUser(loginRequest, user)) {
+      throw new HttpClientErrorException(HttpStatus.FORBIDDEN, "Invalid credentials");
+    }
+
+    return jwtUtil.generateToken(user);
+  }
+
+  public User register(RegisterRequest registerRequest) {
+    Optional<User> user = userRepository.findByEmail(registerRequest.getEmail());
+    if (user.isPresent())
+      throw new HttpClientErrorException(HttpStatus.CONFLICT, "Email already in use");
+
+    return registerNewUser(registerRequest);
+  }
+
+  private User registerNewUser(RegisterRequest registerRequest) {
+    User newUser;
+
+    // Ciframos la contraseña
+    String hashPass = SecurityUtils.encrypt(registerRequest.getPassword());
+    registerRequest.setPassword(hashPass);
+
+    // Aseguramos que tenga un rol, por defecto es cliente
+    if (registerRequest.getRol() == null)
+      registerRequest.setRol(UserRol.CLIENT);
+
+    switch (registerRequest.getRol()) {
+      case HOTEL_ADMIN:
+        HotelManager hm = new HotelManager();
+        BeanUtils.copyProperties(registerRequest, hm);
+        newUser = hotelManagerRepository.save(hm);
+        break;
+
+      case ADMIN: // TODO revisar
+        User admin = new User();
+        BeanUtils.copyProperties(registerRequest, admin);
+        newUser = userRepository.save(admin);
+        break;
+
+      case CLIENT: // Por defecto cliente normal
+      default:
+        Client client = new Client();
+        BeanUtils.copyProperties(registerRequest, client);
+        client.setRol(UserRol.CLIENT);
+        newUser = clientRepository.save(client);
+        break;
+    }
+    return newUser;
+  }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java b/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..518261304ec00dc5c48dd4f860a519cb46b03f75
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/utils/JwtUtil.java
@@ -0,0 +1,85 @@
+package com.uva.authentication.utils;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.io.Decoders;
+import io.jsonwebtoken.security.Keys;
+
+import java.security.Key;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import com.uva.authentication.models.remote.User;
+
+@Component
+public class JwtUtil {
+
+  @Value("${security.jwt.secret-key}")
+  private String secretKey;
+
+  @Value("${security.jwt.expiration-time}")
+  private long jwtExpiration;
+
+  public String extractUsername(String token) {
+    return extractClaim(token, Claims::getSubject);
+  }
+
+  public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
+    final Claims claims = extractAllClaims(token);
+    return claimsResolver.apply(claims);
+  }
+
+  public long getExpirationTime() {
+    return jwtExpiration;
+  }
+
+  public String generateToken(User user) {
+    Map<String, Object> extraClaims = new HashMap<>();
+    extraClaims.put("email", user.getEmail());
+    extraClaims.put("rol", user.getRol());
+    extraClaims.put("user", user);
+    long expiration = jwtExpiration;
+
+    return Jwts
+        .builder()
+        .setClaims(extraClaims)
+        .setSubject(user.getName())
+        .setIssuedAt(new Date(System.currentTimeMillis()))
+        .setExpiration(new Date(System.currentTimeMillis() + expiration))
+        .signWith(getSignInKey(), SignatureAlgorithm.HS256)
+        .compact();
+  }
+
+  public boolean isTokenValid(String token, User user) {
+    final String username = extractUsername(token);
+    return (username.equals(user.getName())) && !isTokenExpired(token);
+  }
+
+  private boolean isTokenExpired(String token) {
+    return extractExpiration(token).before(new Date());
+  }
+
+  private Date extractExpiration(String token) {
+    return extractClaim(token, Claims::getExpiration);
+  }
+
+  private Claims extractAllClaims(String token) {
+    return Jwts
+        .parserBuilder()
+        .setSigningKey(getSignInKey())
+        .build()
+        .parseClaimsJws(token)
+        .getBody();
+  }
+
+  private Key getSignInKey() {
+    byte[] keyBytes = Decoders.BASE64.decode(secretKey);
+    return Keys.hmacShaKeyFor(keyBytes);
+  }
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/utils/SecurityUtils.java b/java/services/auth/src/main/java/com/uva/authentication/utils/SecurityUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..2df069eabbe53bdeaccbdbd58094bf8022ff35c7
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/utils/SecurityUtils.java
@@ -0,0 +1,18 @@
+package com.uva.authentication.utils;
+
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+public class SecurityUtils {
+
+  private static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+
+  public static String encrypt(String value) {
+    return encoder.encode(value);
+  }
+
+  // Método para comparar la contraseña ingresada con el hash almacenado
+  public static boolean checkPassword(String rawPassword, String encodedPassword) {
+    return encoder.matches(rawPassword, encodedPassword); // Comparar la contraseña con el hash
+  }
+  
+}
diff --git a/java/services/auth/src/main/resources/application.properties b/java/services/auth/src/main/resources/application.properties
index 394adbeb066350dbc703341658ee10a64b666856..f08d9f6bd82253e53914fa3c4b695d4c25ba6f24 100644
--- a/java/services/auth/src/main/resources/application.properties
+++ b/java/services/auth/src/main/resources/application.properties
@@ -8,4 +8,9 @@ spring.datasource.password=password
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
 # Usar esto para alternar entre las exposición del room repository ya que no es necesario su uso pero por defecto, al no cubrir su ruta, se expone
-# spring.data.rest.base-path=false
\ No newline at end of file
+# spring.data.rest.base-path=false
+security.jwt.secret-key=3cfa76ef14937c1c0ea519f8fc057a80fcd04a7420f8e8bcd0a7567c272e007b
+# 1h in millisecond
+security.jwt.expiration-time=3600000
+
+external.services.users.baseurl=http://localhost:8080/users
\ No newline at end of file
diff --git a/java/services/bookings/.gitignore b/java/services/bookings/.gitignore
deleted file mode 100644
index 549e00a2a96fa9d7c5dbc9859664a78d980158c2..0000000000000000000000000000000000000000
--- a/java/services/bookings/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
diff --git a/java/services/bookings/Dockerfile b/java/services/bookings/Dockerfile
deleted file mode 100644
index 8d0b79d6514534deddac782fc9367bcdbcaf89c3..0000000000000000000000000000000000000000
--- a/java/services/bookings/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM maven:3-openjdk-17 AS maven
-WORKDIR /app
-COPY ./ ./
-RUN mvn -Dmaven.test.skip clean package
-FROM openjdk:17-jdk-oracle
-ARG JAR_FILE=/app/target/*.jar
-COPY --from=maven ${JAR_FILE} app.jar
-ENV PORT 8080
-EXPOSE $PORT
-ENTRYPOINT ["java","-jar", "/app.jar"]
\ No newline at end of file
diff --git a/java/services/bookings/mvnw b/java/services/bookings/mvnw
deleted file mode 100755
index 19529ddf8c6eaa08c5c75ff80652d21ce4b72f8c..0000000000000000000000000000000000000000
--- a/java/services/bookings/mvnw
+++ /dev/null
@@ -1,259 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.3.2
-#
-# Optional ENV vars
-# -----------------
-#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
-#   MVNW_REPOURL - repo url base for downloading maven distribution
-#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
-# ----------------------------------------------------------------------------
-
-set -euf
-[ "${MVNW_VERBOSE-}" != debug ] || set -x
-
-# OS specific support.
-native_path() { printf %s\\n "$1"; }
-case "$(uname)" in
-CYGWIN* | MINGW*)
-  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
-  native_path() { cygpath --path --windows "$1"; }
-  ;;
-esac
-
-# set JAVACMD and JAVACCMD
-set_java_home() {
-  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
-  if [ -n "${JAVA_HOME-}" ]; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
-      # IBM's JDK on AIX uses strange locations for the executables
-      JAVACMD="$JAVA_HOME/jre/sh/java"
-      JAVACCMD="$JAVA_HOME/jre/sh/javac"
-    else
-      JAVACMD="$JAVA_HOME/bin/java"
-      JAVACCMD="$JAVA_HOME/bin/javac"
-
-      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
-        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
-        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
-        return 1
-      fi
-    fi
-  else
-    JAVACMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v java
-    )" || :
-    JAVACCMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v javac
-    )" || :
-
-    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
-      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
-      return 1
-    fi
-  fi
-}
-
-# hash string like Java String::hashCode
-hash_string() {
-  str="${1:-}" h=0
-  while [ -n "$str" ]; do
-    char="${str%"${str#?}"}"
-    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
-    str="${str#?}"
-  done
-  printf %x\\n $h
-}
-
-verbose() { :; }
-[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
-
-die() {
-  printf %s\\n "$1" >&2
-  exit 1
-}
-
-trim() {
-  # MWRAPPER-139:
-  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
-  #   Needed for removing poorly interpreted newline sequences when running in more
-  #   exotic environments such as mingw bash on Windows.
-  printf "%s" "${1}" | tr -d '[:space:]'
-}
-
-# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
-while IFS="=" read -r key value; do
-  case "${key-}" in
-  distributionUrl) distributionUrl=$(trim "${value-}") ;;
-  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
-  esac
-done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-
-case "${distributionUrl##*/}" in
-maven-mvnd-*bin.*)
-  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
-  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
-  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
-  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
-  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
-  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
-  *)
-    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
-    distributionPlatform=linux-amd64
-    ;;
-  esac
-  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
-  ;;
-maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
-*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
-esac
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
-distributionUrlName="${distributionUrl##*/}"
-distributionUrlNameMain="${distributionUrlName%.*}"
-distributionUrlNameMain="${distributionUrlNameMain%-bin}"
-MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
-MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
-
-exec_maven() {
-  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
-  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
-}
-
-if [ -d "$MAVEN_HOME" ]; then
-  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  exec_maven "$@"
-fi
-
-case "${distributionUrl-}" in
-*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
-*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
-esac
-
-# prepare tmp dir
-if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
-  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
-  trap clean HUP INT TERM EXIT
-else
-  die "cannot create temp dir"
-fi
-
-mkdir -p -- "${MAVEN_HOME%/*}"
-
-# Download and Install Apache Maven
-verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-verbose "Downloading from: $distributionUrl"
-verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-# select .zip or .tar.gz
-if ! command -v unzip >/dev/null; then
-  distributionUrl="${distributionUrl%.zip}.tar.gz"
-  distributionUrlName="${distributionUrl##*/}"
-fi
-
-# verbose opt
-__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
-[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
-
-# normalize http auth
-case "${MVNW_PASSWORD:+has-password}" in
-'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-esac
-
-if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
-  verbose "Found wget ... using wget"
-  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
-elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
-  verbose "Found curl ... using curl"
-  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
-elif set_java_home; then
-  verbose "Falling back to use Java to download"
-  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
-  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
-  cat >"$javaSource" <<-END
-	public class Downloader extends java.net.Authenticator
-	{
-	  protected java.net.PasswordAuthentication getPasswordAuthentication()
-	  {
-	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
-	  }
-	  public static void main( String[] args ) throws Exception
-	  {
-	    setDefault( new Downloader() );
-	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
-	  }
-	}
-	END
-  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
-  verbose " - Compiling Downloader.java ..."
-  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
-  verbose " - Running Downloader.java ..."
-  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
-fi
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-if [ -n "${distributionSha256Sum-}" ]; then
-  distributionSha256Result=false
-  if [ "$MVN_CMD" = mvnd.sh ]; then
-    echo "Checksum validation is not supported for maven-mvnd." >&2
-    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  elif command -v sha256sum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  elif command -v shasum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  else
-    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
-    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  fi
-  if [ $distributionSha256Result = false ]; then
-    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
-    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
-    exit 1
-  fi
-fi
-
-# unzip and move
-if command -v unzip >/dev/null; then
-  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
-else
-  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
-fi
-printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
-mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
-
-clean || :
-exec_maven "$@"
diff --git a/java/services/bookings/mvnw.cmd b/java/services/bookings/mvnw.cmd
deleted file mode 100644
index 249bdf3822221aa612d1da2605316cabd7b07e50..0000000000000000000000000000000000000000
--- a/java/services/bookings/mvnw.cmd
+++ /dev/null
@@ -1,149 +0,0 @@
-<# : batch portion
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements.  See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership.  The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License.  You may obtain a copy of the License at
-@REM
-@REM    http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied.  See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.3.2
-@REM
-@REM Optional ENV vars
-@REM   MVNW_REPOURL - repo url base for downloading maven distribution
-@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
-@REM ----------------------------------------------------------------------------
-
-@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
-@SET __MVNW_CMD__=
-@SET __MVNW_ERROR__=
-@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
-@SET PSModulePath=
-@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
-  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
-)
-@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
-@SET __MVNW_PSMODULEP_SAVE=
-@SET __MVNW_ARG0_NAME__=
-@SET MVNW_USERNAME=
-@SET MVNW_PASSWORD=
-@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
-@echo Cannot start maven from wrapper >&2 && exit /b 1
-@GOTO :EOF
-: end batch / begin powershell #>
-
-$ErrorActionPreference = "Stop"
-if ($env:MVNW_VERBOSE -eq "true") {
-  $VerbosePreference = "Continue"
-}
-
-# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
-$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
-if (!$distributionUrl) {
-  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
-}
-
-switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
-  "maven-mvnd-*" {
-    $USE_MVND = $true
-    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
-    $MVN_CMD = "mvnd.cmd"
-    break
-  }
-  default {
-    $USE_MVND = $false
-    $MVN_CMD = $script -replace '^mvnw','mvn'
-    break
-  }
-}
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-if ($env:MVNW_REPOURL) {
-  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
-  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
-}
-$distributionUrlName = $distributionUrl -replace '^.*/',''
-$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
-$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
-if ($env:MAVEN_USER_HOME) {
-  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
-}
-$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
-$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
-
-if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
-  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
-  exit $?
-}
-
-if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
-  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
-}
-
-# prepare tmp dir
-$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
-$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
-$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
-trap {
-  if ($TMP_DOWNLOAD_DIR.Exists) {
-    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-  }
-}
-
-New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
-
-# Download and Install Apache Maven
-Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-Write-Verbose "Downloading from: $distributionUrl"
-Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-$webclient = New-Object System.Net.WebClient
-if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
-  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
-}
-[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
-if ($distributionSha256Sum) {
-  if ($USE_MVND) {
-    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
-  }
-  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
-  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
-    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
-  }
-}
-
-# unzip and move
-Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
-Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
-try {
-  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
-} catch {
-  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
-    Write-Error "fail to move MAVEN_HOME"
-  }
-} finally {
-  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-}
-
-Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/java/services/bookings/pom.xml b/java/services/bookings/pom.xml
deleted file mode 100644
index 957ab2baae5bc9cd55fd13fa4610617dcf4153a0..0000000000000000000000000000000000000000
--- a/java/services/bookings/pom.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<parent>
-		<groupId>org.springframework.boot</groupId>
-		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>3.3.4</version>
-		<relativePath/> <!-- lookup parent from repository -->
-	</parent>
-	<groupId>com.uva</groupId>
-	<artifactId>bookingService</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
-	<name>bookingService</name>
-	<description>Booking Microservice</description>
-	<url/>
-	<licenses>
-		<license/>
-	</licenses>
-	<developers>
-		<developer/>
-	</developers>
-	<scm>
-		<connection/>
-		<developerConnection/>
-		<tag/>
-		<url/>
-	</scm>
-	<properties>
-		<java.version>17</java.version>
-	</properties>
-	<dependencies>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-jpa</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-rest</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>com.mysql</groupId>
-			<artifactId>mysql-connector-j</artifactId>
-			<scope>runtime</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-test</artifactId>
-			<scope>test</scope>
-		</dependency>
-	</dependencies>
-
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
-			</plugin>
-		</plugins>
-	</build>
-
-</project>
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/Controllers/BookingController.java b/java/services/bookings/src/main/java/com/uva/bookings/Controllers/BookingController.java
deleted file mode 100644
index 66b49481d04a156fb1a4ab509612ca3a7a601234..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/java/com/uva/bookings/Controllers/BookingController.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package com.uva.bookings.Controllers;
-
-import com.uva.bookings.Models.Booking;
-import com.uva.bookings.Repositories.BookingRepository;
-
-import jakarta.transaction.Transactional;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.client.RestTemplate;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/bookings")
-@CrossOrigin(origins = "*")
-public class BookingController {
-
-    @Autowired
-    private BookingRepository bookingRepository;
-
-    @Autowired
-    private RestTemplate restTemplate;
-
-    @GetMapping
-    public ResponseEntity<List<Booking>> getBookings(
-            @RequestParam(required = false) String startDate,
-            @RequestParam(required = false) String endDate,
-            @RequestParam(required = false) Integer roomId) {
-    
-        // Si no se proporcionan filtros, devolver todas las reservas
-        if (startDate == null && endDate == null && roomId == null) {
-            return ResponseEntity.ok(bookingRepository.findAll());
-        }
-    
-        // Obtener reservas filtradas por los parámetros dados
-        List<Booking> bookings = bookingRepository.findByFilters(startDate, endDate, roomId);
-        if (bookings.isEmpty()) {
-            return ResponseEntity.noContent().build();
-        }
-    
-        return ResponseEntity.ok(bookings);
-    }    
-
-    @PostMapping
-    public Booking createBooking(@RequestBody Booking booking) {
-        // Llamada al microservicio de usuarios para validar al usuario
-        ResponseEntity<Void> userResponse = restTemplate.exchange(
-            "http://user-service/users/{userId}",
-            HttpMethod.GET,
-            null,
-            Void.class,
-            booking.getUserId()
-        );
-        if (!userResponse.getStatusCode().is2xxSuccessful()) {
-            throw new RuntimeException("User not found");
-        }
-
-        // Llamada al microservicio de habitaciones para validar la habitación
-        ResponseEntity<Void> roomResponse = restTemplate.exchange(
-            "http://room-service/rooms/{roomId}",
-            HttpMethod.GET,
-            null,
-            Void.class,
-            booking.getRoomId()
-        );
-        if (!roomResponse.getStatusCode().is2xxSuccessful()) {
-            throw new RuntimeException("Room not found");
-        }
-
-        // Verificar disponibilidad
-        List<Booking> existingBookings = bookingRepository.findByRoomIdAndDateRange(
-                booking.getRoomId(), booking.getStartDate(), booking.getEndDate());
-
-        if (!existingBookings.isEmpty()) {
-            throw new RuntimeException("Room is not available for the selected dates");
-        }
-
-        return bookingRepository.save(booking);
-    }
-
-    @GetMapping("/{id}")
-    public Booking getBookingById(@PathVariable Integer id) {
-        return bookingRepository.findById(id)
-                .orElseThrow(() -> new RuntimeException("Booking not found"));
-    }
-
-    @GetMapping(params = "userId")
-    public ResponseEntity<List<Booking>> getBookingsByUserId(@RequestParam Integer userId) {
-        // Llamada al microservicio de usuarios para validar la existencia del usuario
-        ResponseEntity<Void> userResponse = restTemplate.exchange(
-            "http://user-service/users/{userId}",
-            HttpMethod.GET,
-            null,
-            Void.class,
-            userId
-        );
-
-        if (!userResponse.getStatusCode().is2xxSuccessful()) {
-            return ResponseEntity.noContent().build();
-        }
-
-        List<Booking> bookings = bookingRepository.findByUserId(userId);
-        if (bookings.isEmpty()) {
-            return ResponseEntity.noContent().build();
-        }
-        return ResponseEntity.ok(bookings);
-    }
-
-    @DeleteMapping("/{id}")
-    @Transactional
-    public ResponseEntity<Void> deleteBooking(@PathVariable Integer id) {
-        try {
-            if (!bookingRepository.existsById(id))
-                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
-
-            bookingRepository.deleteBookingById(id);
-            return new ResponseEntity<>(HttpStatus.ACCEPTED);
-        } catch (Exception e) {
-            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
-        }
-    }
-}
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/GlobalExceptionHandler.java b/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/GlobalExceptionHandler.java
deleted file mode 100644
index 8a9f4447dd4c4a94fbc32379ced1c86e8bd75e8c..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.uva.bookings.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-@ControllerAdvice
-public class GlobalExceptionHandler {
-
-    @ExceptionHandler(HotelNotFoundException.class)
-    public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
-    }
-
-    @ExceptionHandler(InvalidRequestException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidRequest(InvalidRequestException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    @ExceptionHandler(InvalidDateRangeException.class)
-    public ResponseEntity<Map<String, Object>> handleInvalidDateRange(InvalidDateRangeException ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
-    }
-
-    @ExceptionHandler(Exception.class)
-    public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
-        Map<String, Object> body = new HashMap<>();
-        body.put("timestamp", LocalDateTime.now());
-        body.put("message", "An unexpected error occurred: " + ex.getMessage());
-
-        return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
-    }
-}
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/HotelNotFoundException.java b/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/HotelNotFoundException.java
deleted file mode 100644
index b0f7409bd4ea5bf89816d979c1643dccbe2dea47..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/java/com/uva/bookings/Exceptions/HotelNotFoundException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.bookings.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.NOT_FOUND)  // Devuelve un 404 cuando se lanza la excepción
-public class HotelNotFoundException extends RuntimeException {
-    public HotelNotFoundException(int id) {
-        super("Hotel not found with id: " + id);
-    }
-}
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/Models/Booking.java b/java/services/bookings/src/main/java/com/uva/bookings/Models/Booking.java
deleted file mode 100644
index 269daf37234145f3d248ff0782e3b99c0b138168..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/java/com/uva/bookings/Models/Booking.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.uva.bookings.Models;
-
-import jakarta.persistence.Basic;
-import jakarta.persistence.CascadeType;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "bookings")
-public class Booking {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Basic(optional = false)
-    private int id;
-    @Column(name = "user_id", nullable = false)
-    private int userId;
-    @Column(name = "room_id", nullable = false)
-    private int roomId;
-    @Column(name = "start_date", nullable = false)
-    private LocalDate startDate;
-    @Column(name = "end_date", nullable = false)
-    private LocalDate endDate;
-
-    public Booking() {
-    }
-
-    public Booking(int id, int userId, int roomID, LocalDate startDate, LocalDate endDate) {
-        this.id = id;
-        this.userId = userId;
-        this.roomId = roomID;
-        this.startDate = startDate;
-        this.endDate = endDate;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public int getId() {
-        return this.id;
-    }
-
-    public void setUserId(int userId) {
-        this.userId = userId;
-    }
-
-    public int getUserId() {
-        return this.userId;
-    }
-
-    public void setRoomId(int roomID) {
-        this.roomId = roomID;
-    }
-
-    public int getRoomId() {
-        return this.roomId;
-    }
-
-    public void setStartDate(LocalDate startDate) {
-        this.startDate = startDate;
-    }
-
-    public LocalDate getStartDate() {
-        return this.startDate;
-    }
-
-    public void setEndDate(LocalDate endDate) {
-        this.endDate = endDate;
-    }
-
-    public LocalDate getEndDate() {
-        return this.endDate;
-    }
-
-}
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/Repositories/BookingRepository.java b/java/services/bookings/src/main/java/com/uva/bookings/Repositories/BookingRepository.java
deleted file mode 100644
index 8459911ba59cbf0095b2a7406c0022004f17cd9f..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/java/com/uva/bookings/Repositories/BookingRepository.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// BookingRepository.java
-package com.uva.bookings.Repositories;
-
-import com.uva.bookings.Models.Booking;
-
-import jakarta.transaction.Transactional;
-
-import java.time.LocalDate;
-import java.util.List;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-
-public interface BookingRepository extends JpaRepository<Booking, Integer> {
-
-    @Query("SELECT b FROM Booking b WHERE b.roomId = ?1 AND b.startDate < ?2 AND b.endDate > ?3")
-    List<Booking> findByRoomIdAndDateRange(@Param("roomId") int roomId, @Param("startDate") LocalDate startDate,
-            @Param("endDate") LocalDate endDate);
-
-    @Transactional
-    @Modifying
-    @Query("DELETE FROM Booking b WHERE b.id = ?1")
-    void deleteBookingById(@Param("id") Integer id);
-
-
-    List<Booking> findByUserId(Integer userId);
-
-    @Query("SELECT b FROM Booking b WHERE "
-     + "(:roomId IS NULL OR b.roomId = :roomId) AND "
-     + "(:startDate IS NULL OR b.startDate >= :startDate) AND "
-     + "(:endDate IS NULL OR b.endDate <= :endDate)")
-    List<Booking> findByFilters(@Param("startDate") String startDate, 
-                            @Param("endDate") String endDate, 
-                            @Param("roomId") Integer roomId);
-
-
-
-}
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/bookingServiceApplication.java b/java/services/bookings/src/main/java/com/uva/bookings/bookingServiceApplication.java
deleted file mode 100644
index ae4765caf5111f18fdbceafd5a66272e8aafd775..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/java/com/uva/bookings/bookingServiceApplication.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.bookings;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class bookingServiceApplication {
-
-	public static void main(String[] args) {
-		SpringApplication.run(bookingServiceApplication.class, args);
-	}
-
-}
diff --git a/java/services/bookings/src/main/java/com/uva/bookings/config/RestTemplateConfig.java b/java/services/bookings/src/main/java/com/uva/bookings/config/RestTemplateConfig.java
deleted file mode 100644
index 9891319840494a78fb1f0c8c67a1001461d4467b..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/java/com/uva/bookings/config/RestTemplateConfig.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.uva.bookings.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.client.RestTemplate;
-
-@Configuration
-public class RestTemplateConfig {
-
-    @Bean
-    public RestTemplate restTemplate() {
-        return new RestTemplate();
-    }
-}
diff --git a/java/services/bookings/src/main/resources/application.properties b/java/services/bookings/src/main/resources/application.properties
deleted file mode 100644
index afaa0e3df29833b5a13dc71cbbdfb523897f4cc8..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/main/resources/application.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-spring.application.name=bookingService
-server.port=8131
-spring.jpa.hibernate.ddl-auto=update
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
-spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/RoomsBooking?createDatabaseIfNotExist=true
-spring.datasource.username=user
-spring.datasource.password=password
-spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-
-# Usar esto para alternar entre las exposición del room repository ya que no es necesario su uso pero por defecto, al no cubrir su ruta, se expone
-# spring.data.rest.base-path=false
\ No newline at end of file
diff --git a/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java
deleted file mode 100644
index 3b50599492c36017391c0dcabd81573f123a809a..0000000000000000000000000000000000000000
--- a/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.roomBooking;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class RoomBookingApplicationTests {
-
-	@Test
-	void contextLoads() {
-	}
-
-}
diff --git a/java/services/check_service.sh b/java/services/check_service.sh
deleted file mode 100644
index 2a474f277d1a5b2d2974f793b9f2dd4b169bb6ee..0000000000000000000000000000000000000000
--- a/java/services/check_service.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/bash
-servicesdir="$PWD"
-for i in $(ls $servicesdir); do
-  if [ -d "$servicesdir/$i" ]; then
-    logfile="/tmp/debug_$i.log"
-    echo -n Log file for $i service: 
-    [ ! -f ] && echo -n " NOT"
-    echo " FOUND"
-  fi
-done
-
-for i in {0..30..10}; do
-  port=$((8101 + $i))
-  curl "http://localhost:$port" > /dev/null 2>/dev/null
-  if [ $? -eq 0 ]; then
-    echo "Port $port is open"
-  else
-    echo "Port $port is closed"
-  fi
-done
\ No newline at end of file
diff --git a/java/services/hotels/.gitignore b/java/services/hotels/.gitignore
deleted file mode 100644
index 549e00a2a96fa9d7c5dbc9859664a78d980158c2..0000000000000000000000000000000000000000
--- a/java/services/hotels/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
diff --git a/java/services/hotels/.mvn/wrapper/maven-wrapper.properties b/java/services/hotels/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index d58dfb70bab565a697e6854eb012d17e0fd39bd4..0000000000000000000000000000000000000000
--- a/java/services/hotels/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-wrapperVersion=3.3.2
-distributionType=only-script
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
diff --git a/java/services/hotels/Dockerfile b/java/services/hotels/Dockerfile
deleted file mode 100644
index 8d0b79d6514534deddac782fc9367bcdbcaf89c3..0000000000000000000000000000000000000000
--- a/java/services/hotels/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM maven:3-openjdk-17 AS maven
-WORKDIR /app
-COPY ./ ./
-RUN mvn -Dmaven.test.skip clean package
-FROM openjdk:17-jdk-oracle
-ARG JAR_FILE=/app/target/*.jar
-COPY --from=maven ${JAR_FILE} app.jar
-ENV PORT 8080
-EXPOSE $PORT
-ENTRYPOINT ["java","-jar", "/app.jar"]
\ No newline at end of file
diff --git a/java/services/hotels/mvnw b/java/services/hotels/mvnw
deleted file mode 100755
index 19529ddf8c6eaa08c5c75ff80652d21ce4b72f8c..0000000000000000000000000000000000000000
--- a/java/services/hotels/mvnw
+++ /dev/null
@@ -1,259 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.3.2
-#
-# Optional ENV vars
-# -----------------
-#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
-#   MVNW_REPOURL - repo url base for downloading maven distribution
-#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
-# ----------------------------------------------------------------------------
-
-set -euf
-[ "${MVNW_VERBOSE-}" != debug ] || set -x
-
-# OS specific support.
-native_path() { printf %s\\n "$1"; }
-case "$(uname)" in
-CYGWIN* | MINGW*)
-  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
-  native_path() { cygpath --path --windows "$1"; }
-  ;;
-esac
-
-# set JAVACMD and JAVACCMD
-set_java_home() {
-  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
-  if [ -n "${JAVA_HOME-}" ]; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
-      # IBM's JDK on AIX uses strange locations for the executables
-      JAVACMD="$JAVA_HOME/jre/sh/java"
-      JAVACCMD="$JAVA_HOME/jre/sh/javac"
-    else
-      JAVACMD="$JAVA_HOME/bin/java"
-      JAVACCMD="$JAVA_HOME/bin/javac"
-
-      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
-        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
-        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
-        return 1
-      fi
-    fi
-  else
-    JAVACMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v java
-    )" || :
-    JAVACCMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v javac
-    )" || :
-
-    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
-      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
-      return 1
-    fi
-  fi
-}
-
-# hash string like Java String::hashCode
-hash_string() {
-  str="${1:-}" h=0
-  while [ -n "$str" ]; do
-    char="${str%"${str#?}"}"
-    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
-    str="${str#?}"
-  done
-  printf %x\\n $h
-}
-
-verbose() { :; }
-[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
-
-die() {
-  printf %s\\n "$1" >&2
-  exit 1
-}
-
-trim() {
-  # MWRAPPER-139:
-  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
-  #   Needed for removing poorly interpreted newline sequences when running in more
-  #   exotic environments such as mingw bash on Windows.
-  printf "%s" "${1}" | tr -d '[:space:]'
-}
-
-# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
-while IFS="=" read -r key value; do
-  case "${key-}" in
-  distributionUrl) distributionUrl=$(trim "${value-}") ;;
-  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
-  esac
-done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-
-case "${distributionUrl##*/}" in
-maven-mvnd-*bin.*)
-  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
-  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
-  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
-  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
-  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
-  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
-  *)
-    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
-    distributionPlatform=linux-amd64
-    ;;
-  esac
-  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
-  ;;
-maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
-*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
-esac
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
-distributionUrlName="${distributionUrl##*/}"
-distributionUrlNameMain="${distributionUrlName%.*}"
-distributionUrlNameMain="${distributionUrlNameMain%-bin}"
-MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
-MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
-
-exec_maven() {
-  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
-  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
-}
-
-if [ -d "$MAVEN_HOME" ]; then
-  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  exec_maven "$@"
-fi
-
-case "${distributionUrl-}" in
-*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
-*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
-esac
-
-# prepare tmp dir
-if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
-  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
-  trap clean HUP INT TERM EXIT
-else
-  die "cannot create temp dir"
-fi
-
-mkdir -p -- "${MAVEN_HOME%/*}"
-
-# Download and Install Apache Maven
-verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-verbose "Downloading from: $distributionUrl"
-verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-# select .zip or .tar.gz
-if ! command -v unzip >/dev/null; then
-  distributionUrl="${distributionUrl%.zip}.tar.gz"
-  distributionUrlName="${distributionUrl##*/}"
-fi
-
-# verbose opt
-__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
-[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
-
-# normalize http auth
-case "${MVNW_PASSWORD:+has-password}" in
-'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-esac
-
-if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
-  verbose "Found wget ... using wget"
-  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
-elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
-  verbose "Found curl ... using curl"
-  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
-elif set_java_home; then
-  verbose "Falling back to use Java to download"
-  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
-  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
-  cat >"$javaSource" <<-END
-	public class Downloader extends java.net.Authenticator
-	{
-	  protected java.net.PasswordAuthentication getPasswordAuthentication()
-	  {
-	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
-	  }
-	  public static void main( String[] args ) throws Exception
-	  {
-	    setDefault( new Downloader() );
-	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
-	  }
-	}
-	END
-  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
-  verbose " - Compiling Downloader.java ..."
-  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
-  verbose " - Running Downloader.java ..."
-  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
-fi
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-if [ -n "${distributionSha256Sum-}" ]; then
-  distributionSha256Result=false
-  if [ "$MVN_CMD" = mvnd.sh ]; then
-    echo "Checksum validation is not supported for maven-mvnd." >&2
-    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  elif command -v sha256sum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  elif command -v shasum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  else
-    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
-    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  fi
-  if [ $distributionSha256Result = false ]; then
-    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
-    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
-    exit 1
-  fi
-fi
-
-# unzip and move
-if command -v unzip >/dev/null; then
-  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
-else
-  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
-fi
-printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
-mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
-
-clean || :
-exec_maven "$@"
diff --git a/java/services/hotels/mvnw.cmd b/java/services/hotels/mvnw.cmd
deleted file mode 100644
index 249bdf3822221aa612d1da2605316cabd7b07e50..0000000000000000000000000000000000000000
--- a/java/services/hotels/mvnw.cmd
+++ /dev/null
@@ -1,149 +0,0 @@
-<# : batch portion
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements.  See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership.  The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License.  You may obtain a copy of the License at
-@REM
-@REM    http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied.  See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.3.2
-@REM
-@REM Optional ENV vars
-@REM   MVNW_REPOURL - repo url base for downloading maven distribution
-@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
-@REM ----------------------------------------------------------------------------
-
-@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
-@SET __MVNW_CMD__=
-@SET __MVNW_ERROR__=
-@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
-@SET PSModulePath=
-@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
-  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
-)
-@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
-@SET __MVNW_PSMODULEP_SAVE=
-@SET __MVNW_ARG0_NAME__=
-@SET MVNW_USERNAME=
-@SET MVNW_PASSWORD=
-@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
-@echo Cannot start maven from wrapper >&2 && exit /b 1
-@GOTO :EOF
-: end batch / begin powershell #>
-
-$ErrorActionPreference = "Stop"
-if ($env:MVNW_VERBOSE -eq "true") {
-  $VerbosePreference = "Continue"
-}
-
-# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
-$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
-if (!$distributionUrl) {
-  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
-}
-
-switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
-  "maven-mvnd-*" {
-    $USE_MVND = $true
-    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
-    $MVN_CMD = "mvnd.cmd"
-    break
-  }
-  default {
-    $USE_MVND = $false
-    $MVN_CMD = $script -replace '^mvnw','mvn'
-    break
-  }
-}
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-if ($env:MVNW_REPOURL) {
-  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
-  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
-}
-$distributionUrlName = $distributionUrl -replace '^.*/',''
-$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
-$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
-if ($env:MAVEN_USER_HOME) {
-  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
-}
-$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
-$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
-
-if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
-  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
-  exit $?
-}
-
-if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
-  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
-}
-
-# prepare tmp dir
-$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
-$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
-$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
-trap {
-  if ($TMP_DOWNLOAD_DIR.Exists) {
-    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-  }
-}
-
-New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
-
-# Download and Install Apache Maven
-Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-Write-Verbose "Downloading from: $distributionUrl"
-Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-$webclient = New-Object System.Net.WebClient
-if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
-  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
-}
-[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
-if ($distributionSha256Sum) {
-  if ($USE_MVND) {
-    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
-  }
-  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
-  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
-    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
-  }
-}
-
-# unzip and move
-Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
-Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
-try {
-  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
-} catch {
-  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
-    Write-Error "fail to move MAVEN_HOME"
-  }
-} finally {
-  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-}
-
-Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/java/services/hotels/pom.xml b/java/services/hotels/pom.xml
deleted file mode 100644
index fd6521678ea85077d527d118898ab02c8c8d9e79..0000000000000000000000000000000000000000
--- a/java/services/hotels/pom.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<parent>
-		<groupId>org.springframework.boot</groupId>
-		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>3.3.4</version>
-		<relativePath/> <!-- lookup parent from repository -->
-	</parent>
-	<groupId>com.uva</groupId>
-	<artifactId>hotelService</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
-	<name>hotelService</name>
-	<description>Hotel Microservice REST</description>
-	<url/>
-	<licenses>
-		<license/>
-	</licenses>
-	<developers>
-		<developer/>
-	</developers>
-	<scm>
-		<connection/>
-		<developerConnection/>
-		<tag/>
-		<url/>
-	</scm>
-	<properties>
-		<java.version>17</java.version>
-	</properties>
-	<dependencies>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-jpa</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-rest</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>com.mysql</groupId>
-			<artifactId>mysql-connector-j</artifactId>
-			<scope>runtime</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-test</artifactId>
-			<scope>test</scope>
-		</dependency>
-	</dependencies>
-
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
-			</plugin>
-		</plugins>
-	</build>
-
-</project>
\ No newline at end of file
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Controllers/HotelController.java b/java/services/hotels/src/main/java/com/uva/hotelService/Controllers/HotelController.java
deleted file mode 100644
index fc949f5efce63f12785a858a307ef61b7d41d70d..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Controllers/HotelController.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package com.uva.hotelService.Controllers;
-
-import java.util.List;
-import java.util.Map;
-import java.time.LocalDate;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.client.RestTemplate;
-
-import com.uva.hotelService.Exceptions.HotelNotFoundException;
-import com.uva.hotelService.Exceptions.InvalidDateRangeException;
-import com.uva.hotelService.Exceptions.InvalidRequestException;
-import com.uva.hotelService.Models.Hotel;
-import com.uva.hotelService.Models.Room;
-import com.uva.hotelService.Repositories.HotelRepository;
-import com.uva.hotelService.Repositories.RoomRepository;
-
-@RestController
-@RequestMapping("hotels")
-@CrossOrigin(origins = "*")
-public class HotelController {
-
-    @Autowired
-    private HotelRepository hotelRepository;
-
-    @Autowired
-    private RoomRepository roomRepository;
-
-    @Autowired
-    private RestTemplate restTemplate;
-
-    // Obtener todos los hoteles
-    @GetMapping
-    public List<Hotel> getAllHotels() {
-        return hotelRepository.findAll();
-    }
-
-    // Añadir un hotel con sus habitaciones
-    @PostMapping
-    public ResponseEntity<Hotel> addHotel(@RequestBody Hotel hotel) {
-        Hotel savedHotel = hotelRepository.save(hotel);
-        return new ResponseEntity<>(savedHotel, HttpStatus.CREATED);
-    }
-
-    // Obtener un hotel por su ID
-    @GetMapping("/{id}")
-    public Hotel getHotelById(@PathVariable int id) {
-        return hotelRepository.findById(id)
-                .orElseThrow(() -> new HotelNotFoundException(id));
-    }
-
-    // Borrar un hotel junto con sus habitaciones (borrado en cascada)
-    @DeleteMapping("/{id}")
-    @Transactional
-    public ResponseEntity<Void> deleteHotel(@PathVariable Integer id) {
-        Hotel target = hotelRepository.findById(id)
-                .orElseThrow(() -> new HotelNotFoundException(id));
-        // bookingRepository.deleteAllByHotelId(id);
-        // TODO revisar como se va a hacer cuando se haga lo de reservas
-        String deleteUrl = String.format("http://reservas-service/?hotelId=%d", target.getId());
-        restTemplate.delete(deleteUrl);
-        hotelRepository.delete(target);
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
-    }
-
-    // Obtener habitaciones de un hotel según disponibilidad y fechas
-    @GetMapping("/{hotelId}/rooms")
-    public ResponseEntity<List<Room>> getRoomsFromHotel(
-            @PathVariable int hotelId,
-            @RequestParam(required = false) LocalDate start,
-            @RequestParam(required = false) LocalDate end) {
-
-        List<Room> rooms;
-        rooms = roomRepository.findAllByHotelIdAndAvailable(hotelId, true);
-        if (start != null && end != null) {
-            if (!start.isBefore(end)) {
-                throw new InvalidDateRangeException("La fecha de inicio debe ser anterior a la fecha de fin");
-            }
-            rooms = rooms.stream().filter(
-                    room -> {
-                        // TODO revisar
-                        String url = String.format("http://reservas-service/?hotelId=%d&start=%s&end=%s", room.getId(),
-                                start, end);
-                        return Boolean.parseBoolean(
-                                restTemplate.exchange(
-                                        url,
-                                        HttpMethod.GET,
-                                        null,
-                                        Boolean.class).toString());
-                    }).toList();
-
-        }
-        return new ResponseEntity<>(rooms, HttpStatus.OK);
-    }
-
-    // Actualizar disponibilidad de una habitación específica en un hotel
-    @PatchMapping("/{hotelId}/rooms/{roomId}")
-    public ResponseEntity<Room> updateRoomAvailability(
-            @PathVariable int hotelId,
-            @PathVariable int roomId,
-            @RequestBody Map<String, Boolean> body) {
-
-        if (!body.containsKey("available")) {
-            throw new InvalidRequestException("El campo 'available' es obligatorio");
-        }
-
-        Room targetRoom = roomRepository.findByIdAndHotelId(roomId, hotelId)
-                .orElseThrow(() -> new IllegalArgumentException("Habitación no encontrada"));
-
-        targetRoom.setAvailable(body.get("available"));
-        roomRepository.save(targetRoom);
-
-        return new ResponseEntity<>(targetRoom, HttpStatus.OK);
-    }
-
-    // Obtener los detalles de una habitación específica en un hotel
-    @GetMapping("/{hotelId}/rooms/{roomId}")
-    public Room getRoomByIdFromHotel(
-            @PathVariable int hotelId, @PathVariable int roomId) {
-        return roomRepository.findByIdAndHotelId(roomId, hotelId)
-                .orElseThrow(() -> new HotelNotFoundException(hotelId));
-    }
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/InvalidDateRangeException.java b/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/InvalidDateRangeException.java
deleted file mode 100644
index 5bddd4c9083a7dd7ca896f7af916dbd5f70aab09..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/InvalidDateRangeException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.uva.hotelService.Exceptions;
-
-public class InvalidDateRangeException extends RuntimeException {
-    public InvalidDateRangeException(String message) {
-        super(message);
-    }
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/InvalidRequestException.java b/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/InvalidRequestException.java
deleted file mode 100644
index cd714aa29347e661eff5099c835178a67f38a279..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Exceptions/InvalidRequestException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.hotelService.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class InvalidRequestException extends RuntimeException {
-    public InvalidRequestException(String message) {
-        super(message);
-    }
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Address.java b/java/services/hotels/src/main/java/com/uva/hotelService/Models/Address.java
deleted file mode 100644
index 43bc9642cd9b75d8bd98ea135707e02be1749d04..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Address.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.uva.hotelService.Models;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
-import jakarta.persistence.Basic;
-import jakarta.persistence.CascadeType;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "addresses")
-public class Address {
-
-  @Id
-  @GeneratedValue(strategy = GenerationType.IDENTITY)
-  @Basic(optional = false)
-  private int id;
-
-  @Basic(optional = false)
-  @Column(name = "street_kind")
-  private String streetKind;
-
-  @Basic(optional = false)
-  @Column(name = "street_name")
-  private String streetName;
-
-  @Basic(optional = false)
-  private int number;
-
-  @Basic(optional = false)
-  @Column(name = "post_code")
-  private String postCode;
-
-  @Basic(optional = true)
-  @Column(name = "other_info")
-  private String otherInfo;
-
-  @JsonIgnore
-  @OneToOne(mappedBy = "address", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
-  private Hotel hotel;
-
-  public Address() {
-  }
-
-  public Address(String streetKind, String streetName, int number, String postCode, String otherInfo, Hotel hotel) {
-    setStreetKind(streetKind);
-    setStreetName(streetName);
-    setNumber(number);
-    setPostCode(postCode);
-    setOtherInfo(otherInfo);
-    setHotel(hotel);
-  }
-
-  public int getId() {
-    return this.id;
-  }
-
-  public void setId(int id) {
-    this.id = id;
-  }
-
-  public String getStreetKind() {
-    return this.streetKind;
-  }
-
-  public void setStreetKind(String streetKind) {
-    this.streetKind = streetKind;
-  }
-
-  public String getStreetName() {
-    return this.streetName;
-  }
-
-  public void setStreetName(String streetName) {
-    this.streetName = streetName;
-  }
-
-  public int getNumber() {
-    return this.number;
-  }
-
-  public void setNumber(int number) {
-    this.number = number;
-  }
-
-  public String getPostCode() {
-    return this.postCode;
-  }
-
-  public void setPostCode(String postCode) {
-    this.postCode = postCode;
-  }
-
-  public String getOtherInfo() {
-    return this.otherInfo;
-  }
-
-  public void setOtherInfo(String otherInfo) {
-    this.otherInfo = otherInfo;
-  }
-
-  public Hotel getHotel() {
-    return this.hotel;
-  }
-
-  public void setHotel(Hotel hotel) {
-    this.hotel = hotel;
-  }
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Hotel.java b/java/services/hotels/src/main/java/com/uva/hotelService/Models/Hotel.java
deleted file mode 100644
index 672f8d8b74030707319b6d8368c0bb0f941d90e7..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Hotel.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.uva.hotelService.Models;
-
-import java.util.List;
-import jakarta.persistence.Basic;
-import jakarta.persistence.CascadeType;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.OneToMany;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "hotels")
-// @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
-// property = "id")
-public class Hotel {
-
-  @Id
-  @GeneratedValue(strategy = GenerationType.IDENTITY)
-  @Basic(optional = false)
-  private int id;
-
-  @Basic(optional = false)
-  private String name;
-
-  @JoinColumn(name = "address_id", referencedColumnName = "id")
-  @OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
-  private Address address;
-
-  @OneToMany(mappedBy = "hotel", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
-  private List<Room> rooms;
-
-  public Hotel() {
-  }
-
-  public Hotel(int id, String name, Address address, List<Room> rooms) {
-    setId(id);
-    setName(name);
-    setAddress(address);
-    setRooms(rooms);
-  }
-
-  public int getId() {
-    return this.id;
-  }
-
-  public void setId(int id) {
-    this.id = id;
-  }
-
-  public String getName() {
-    return this.name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public Address getAddress() {
-    return this.address;
-  }
-
-  public void setAddress(Address address) {
-    this.address = address;
-  }
-
-  public List<Room> getRooms() {
-    return this.rooms;
-  }
-
-  public void setRooms(List<Room> rooms) {
-    this.rooms = rooms;
-    rooms.forEach(room -> room.setHotel(this));
-  }
-
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Room.java b/java/services/hotels/src/main/java/com/uva/hotelService/Models/Room.java
deleted file mode 100644
index 0d09d6f81477c0331691c8e4b5e36ac58e0d0d24..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Room.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.uva.hotelService.Models;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import jakarta.persistence.Basic;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "rooms")
-// @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
-// property = "id")
-public class Room {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Basic(optional = false)
-    private int id;
-
-    @ManyToOne
-    @JoinColumn(name = "hotel_id", referencedColumnName = "id")
-    @JsonIgnore
-    private Hotel hotel;
-    @Column(name = "room_number", nullable = false)
-    private String roomNumber;
-    @Column(name = "type", nullable = false)
-    private Tipo type;
-    @Column(name = "available", nullable = false)
-    private boolean available;
-
-    public Room() {
-    }
-
-    public Room(int id, Hotel hotelId, String roomNumber, Tipo type, boolean available) {
-        this.id = id;
-        this.hotel = hotelId;
-        this.roomNumber = roomNumber;
-        this.type = type;
-        this.available = available;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public int getId() {
-        return this.id;
-    }
-
-    public void setHotel(Hotel hotelId) {
-        this.hotel = hotelId;
-    }
-
-    public Hotel getHotel() {
-        return this.hotel;
-    }
-
-    public void setRoomNumber(String roomNumber) {
-        this.roomNumber = roomNumber;
-    }
-
-    public String getRoomNumber() {
-        return this.roomNumber;
-    }
-
-    public void setType(Tipo type) {
-        this.type = type;
-    }
-
-    public Tipo getType() {
-        return this.type;
-    }
-
-    public void setAvailable(boolean available) {
-        this.available = available;
-    }
-
-    public boolean isAvailable() {
-        return this.available;
-    }
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Tipo.java b/java/services/hotels/src/main/java/com/uva/hotelService/Models/Tipo.java
deleted file mode 100644
index b893a7c4e5da3792e6de1d86972c8946d990f9da..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Models/Tipo.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.uva.hotelService.Models;
-
-public enum Tipo {
-    SINGLE,
-    DOUBLE,
-    SUITE
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/Repositories/RoomRepository.java b/java/services/hotels/src/main/java/com/uva/hotelService/Repositories/RoomRepository.java
deleted file mode 100644
index c84a86eb58035937dba9638933036196c2d1a470..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/Repositories/RoomRepository.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.uva.hotelService.Repositories;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-import com.uva.hotelService.Models.Room;
-import java.util.List;
-import java.util.Optional;
-
-public interface RoomRepository extends JpaRepository<Room, Integer> {
-
-    Optional<Room> findByIdAndHotelId(int id, int hotelId);
-
-    List<Room> findAllByHotelId(int hotelId);
-
-    List<Room> findAllByHotelIdAndAvailable(int hotelId, boolean available);
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/config/RestTemplateConfig.java b/java/services/hotels/src/main/java/com/uva/hotelService/config/RestTemplateConfig.java
deleted file mode 100644
index 05af4ebcc1528bb428c9ac6022d61f109c7dc4d5..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/config/RestTemplateConfig.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.uva.hotelService.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.client.RestTemplate;
-
-@Configuration
-public class RestTemplateConfig {
-
-    @Bean
-    public RestTemplate restTemplate() {
-        return new RestTemplate();
-    }
-}
diff --git a/java/services/hotels/src/main/java/com/uva/hotelService/hotelServiceApplication.java b/java/services/hotels/src/main/java/com/uva/hotelService/hotelServiceApplication.java
deleted file mode 100644
index 0068b98f3b84aa2f29a70339223880279ecb7e09..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/java/com/uva/hotelService/hotelServiceApplication.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.hotelService;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class hotelServiceApplication {
-
-	public static void main(String[] args) {
-		SpringApplication.run(hotelServiceApplication.class, args);
-	}
-
-}
diff --git a/java/services/hotels/src/main/resources/application.properties b/java/services/hotels/src/main/resources/application.properties
deleted file mode 100644
index 5021e2005773ae5544474798099ed2b72bb1edb4..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/main/resources/application.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-spring.application.name=hotelService
-server.port=8121
-spring.jpa.hibernate.ddl-auto=update
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
-spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/RoomsBooking?createDatabaseIfNotExist=true
-spring.datasource.username=user
-spring.datasource.password=password
-spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java
deleted file mode 100644
index 3b50599492c36017391c0dcabd81573f123a809a..0000000000000000000000000000000000000000
--- a/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.roomBooking;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class RoomBookingApplicationTests {
-
-	@Test
-	void contextLoads() {
-	}
-
-}
diff --git a/java/services/launch.sh b/java/services/launch.sh
deleted file mode 100644
index 7224e675de8f43307adc80214a8453266d140fbb..0000000000000000000000000000000000000000
--- a/java/services/launch.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#! /usr/bin/bash
-servicesdir="$PWD"
-pidfile=$servicesdir/servers.pid
-echo "Pids of launch `date`" > $pidfile
-for i in $(ls $servicesdir); do
-  if [ -d $servicesdir/$i ]; then
-    cd $servicesdir/$i
-    logfile="/tmp/debug_$i.log"
-    mvn spring-boot:run > $logfile &
-    pid=$!
-    # echo "El servicio se está ejecutando en segundo plano con PID: $pid"
-    # Opcionalmente, puedes guardar el PID en un archivo
-    echo "$i running in pid $pid" >> $pidfile
-    echo Launched $i service, view the log in $logfile
-  fi
-done
diff --git a/java/services/servers.pid b/java/services/servers.pid
deleted file mode 100644
index 689f217b8da2a2b0f56e68aeeebb43cfa149e491..0000000000000000000000000000000000000000
--- a/java/services/servers.pid
+++ /dev/null
@@ -1,5 +0,0 @@
-Pids of launch dom 17 nov 2024 12:30:54 CET
-auth running in pid 104539
-bookings running in pid 104540
-hotels running in pid 104541
-users running in pid 104542
diff --git a/java/services/stop-service.sh b/java/services/stop-service.sh
deleted file mode 100644
index 87a710ea48416c38e6ccfada5a7fe6bb96bdb530..0000000000000000000000000000000000000000
--- a/java/services/stop-service.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-for i in {0..30..10}; do
-  port=$((8101 + $i))
-  kill `sudo lsof -t -i :$port`
-done
\ No newline at end of file
diff --git a/java/services/users/.gitignore b/java/services/users/.gitignore
deleted file mode 100644
index 549e00a2a96fa9d7c5dbc9859664a78d980158c2..0000000000000000000000000000000000000000
--- a/java/services/users/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
diff --git a/java/services/users/.mvn/wrapper/maven-wrapper.properties b/java/services/users/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index d58dfb70bab565a697e6854eb012d17e0fd39bd4..0000000000000000000000000000000000000000
--- a/java/services/users/.mvn/wrapper/maven-wrapper.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-wrapperVersion=3.3.2
-distributionType=only-script
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
diff --git a/java/services/users/Dockerfile b/java/services/users/Dockerfile
deleted file mode 100644
index 8d0b79d6514534deddac782fc9367bcdbcaf89c3..0000000000000000000000000000000000000000
--- a/java/services/users/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM maven:3-openjdk-17 AS maven
-WORKDIR /app
-COPY ./ ./
-RUN mvn -Dmaven.test.skip clean package
-FROM openjdk:17-jdk-oracle
-ARG JAR_FILE=/app/target/*.jar
-COPY --from=maven ${JAR_FILE} app.jar
-ENV PORT 8080
-EXPOSE $PORT
-ENTRYPOINT ["java","-jar", "/app.jar"]
\ No newline at end of file
diff --git a/java/services/users/mvnw b/java/services/users/mvnw
deleted file mode 100755
index 19529ddf8c6eaa08c5c75ff80652d21ce4b72f8c..0000000000000000000000000000000000000000
--- a/java/services/users/mvnw
+++ /dev/null
@@ -1,259 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.3.2
-#
-# Optional ENV vars
-# -----------------
-#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
-#   MVNW_REPOURL - repo url base for downloading maven distribution
-#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
-# ----------------------------------------------------------------------------
-
-set -euf
-[ "${MVNW_VERBOSE-}" != debug ] || set -x
-
-# OS specific support.
-native_path() { printf %s\\n "$1"; }
-case "$(uname)" in
-CYGWIN* | MINGW*)
-  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
-  native_path() { cygpath --path --windows "$1"; }
-  ;;
-esac
-
-# set JAVACMD and JAVACCMD
-set_java_home() {
-  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
-  if [ -n "${JAVA_HOME-}" ]; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
-      # IBM's JDK on AIX uses strange locations for the executables
-      JAVACMD="$JAVA_HOME/jre/sh/java"
-      JAVACCMD="$JAVA_HOME/jre/sh/javac"
-    else
-      JAVACMD="$JAVA_HOME/bin/java"
-      JAVACCMD="$JAVA_HOME/bin/javac"
-
-      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
-        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
-        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
-        return 1
-      fi
-    fi
-  else
-    JAVACMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v java
-    )" || :
-    JAVACCMD="$(
-      'set' +e
-      'unset' -f command 2>/dev/null
-      'command' -v javac
-    )" || :
-
-    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
-      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
-      return 1
-    fi
-  fi
-}
-
-# hash string like Java String::hashCode
-hash_string() {
-  str="${1:-}" h=0
-  while [ -n "$str" ]; do
-    char="${str%"${str#?}"}"
-    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
-    str="${str#?}"
-  done
-  printf %x\\n $h
-}
-
-verbose() { :; }
-[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
-
-die() {
-  printf %s\\n "$1" >&2
-  exit 1
-}
-
-trim() {
-  # MWRAPPER-139:
-  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
-  #   Needed for removing poorly interpreted newline sequences when running in more
-  #   exotic environments such as mingw bash on Windows.
-  printf "%s" "${1}" | tr -d '[:space:]'
-}
-
-# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
-while IFS="=" read -r key value; do
-  case "${key-}" in
-  distributionUrl) distributionUrl=$(trim "${value-}") ;;
-  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
-  esac
-done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
-
-case "${distributionUrl##*/}" in
-maven-mvnd-*bin.*)
-  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
-  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
-  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
-  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
-  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
-  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
-  *)
-    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
-    distributionPlatform=linux-amd64
-    ;;
-  esac
-  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
-  ;;
-maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
-*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
-esac
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
-distributionUrlName="${distributionUrl##*/}"
-distributionUrlNameMain="${distributionUrlName%.*}"
-distributionUrlNameMain="${distributionUrlNameMain%-bin}"
-MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
-MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
-
-exec_maven() {
-  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
-  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
-}
-
-if [ -d "$MAVEN_HOME" ]; then
-  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  exec_maven "$@"
-fi
-
-case "${distributionUrl-}" in
-*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
-*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
-esac
-
-# prepare tmp dir
-if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
-  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
-  trap clean HUP INT TERM EXIT
-else
-  die "cannot create temp dir"
-fi
-
-mkdir -p -- "${MAVEN_HOME%/*}"
-
-# Download and Install Apache Maven
-verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-verbose "Downloading from: $distributionUrl"
-verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-# select .zip or .tar.gz
-if ! command -v unzip >/dev/null; then
-  distributionUrl="${distributionUrl%.zip}.tar.gz"
-  distributionUrlName="${distributionUrl##*/}"
-fi
-
-# verbose opt
-__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
-[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
-
-# normalize http auth
-case "${MVNW_PASSWORD:+has-password}" in
-'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
-esac
-
-if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
-  verbose "Found wget ... using wget"
-  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
-elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
-  verbose "Found curl ... using curl"
-  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
-elif set_java_home; then
-  verbose "Falling back to use Java to download"
-  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
-  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
-  cat >"$javaSource" <<-END
-	public class Downloader extends java.net.Authenticator
-	{
-	  protected java.net.PasswordAuthentication getPasswordAuthentication()
-	  {
-	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
-	  }
-	  public static void main( String[] args ) throws Exception
-	  {
-	    setDefault( new Downloader() );
-	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
-	  }
-	}
-	END
-  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
-  verbose " - Compiling Downloader.java ..."
-  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
-  verbose " - Running Downloader.java ..."
-  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
-fi
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-if [ -n "${distributionSha256Sum-}" ]; then
-  distributionSha256Result=false
-  if [ "$MVN_CMD" = mvnd.sh ]; then
-    echo "Checksum validation is not supported for maven-mvnd." >&2
-    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  elif command -v sha256sum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  elif command -v shasum >/dev/null; then
-    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
-      distributionSha256Result=true
-    fi
-  else
-    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
-    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
-    exit 1
-  fi
-  if [ $distributionSha256Result = false ]; then
-    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
-    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
-    exit 1
-  fi
-fi
-
-# unzip and move
-if command -v unzip >/dev/null; then
-  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
-else
-  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
-fi
-printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
-mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
-
-clean || :
-exec_maven "$@"
diff --git a/java/services/users/mvnw.cmd b/java/services/users/mvnw.cmd
deleted file mode 100644
index 249bdf3822221aa612d1da2605316cabd7b07e50..0000000000000000000000000000000000000000
--- a/java/services/users/mvnw.cmd
+++ /dev/null
@@ -1,149 +0,0 @@
-<# : batch portion
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements.  See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership.  The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License.  You may obtain a copy of the License at
-@REM
-@REM    http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied.  See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.3.2
-@REM
-@REM Optional ENV vars
-@REM   MVNW_REPOURL - repo url base for downloading maven distribution
-@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
-@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
-@REM ----------------------------------------------------------------------------
-
-@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
-@SET __MVNW_CMD__=
-@SET __MVNW_ERROR__=
-@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
-@SET PSModulePath=
-@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
-  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
-)
-@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
-@SET __MVNW_PSMODULEP_SAVE=
-@SET __MVNW_ARG0_NAME__=
-@SET MVNW_USERNAME=
-@SET MVNW_PASSWORD=
-@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
-@echo Cannot start maven from wrapper >&2 && exit /b 1
-@GOTO :EOF
-: end batch / begin powershell #>
-
-$ErrorActionPreference = "Stop"
-if ($env:MVNW_VERBOSE -eq "true") {
-  $VerbosePreference = "Continue"
-}
-
-# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
-$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
-if (!$distributionUrl) {
-  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
-}
-
-switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
-  "maven-mvnd-*" {
-    $USE_MVND = $true
-    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
-    $MVN_CMD = "mvnd.cmd"
-    break
-  }
-  default {
-    $USE_MVND = $false
-    $MVN_CMD = $script -replace '^mvnw','mvn'
-    break
-  }
-}
-
-# apply MVNW_REPOURL and calculate MAVEN_HOME
-# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
-if ($env:MVNW_REPOURL) {
-  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
-  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
-}
-$distributionUrlName = $distributionUrl -replace '^.*/',''
-$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
-$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
-if ($env:MAVEN_USER_HOME) {
-  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
-}
-$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
-$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
-
-if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
-  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
-  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
-  exit $?
-}
-
-if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
-  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
-}
-
-# prepare tmp dir
-$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
-$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
-$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
-trap {
-  if ($TMP_DOWNLOAD_DIR.Exists) {
-    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-  }
-}
-
-New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
-
-# Download and Install Apache Maven
-Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
-Write-Verbose "Downloading from: $distributionUrl"
-Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
-
-$webclient = New-Object System.Net.WebClient
-if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
-  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
-}
-[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
-$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
-
-# If specified, validate the SHA-256 sum of the Maven distribution zip file
-$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
-if ($distributionSha256Sum) {
-  if ($USE_MVND) {
-    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
-  }
-  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
-  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
-    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
-  }
-}
-
-# unzip and move
-Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
-Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
-try {
-  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
-} catch {
-  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
-    Write-Error "fail to move MAVEN_HOME"
-  }
-} finally {
-  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
-  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
-}
-
-Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
diff --git a/java/services/users/pom.xml b/java/services/users/pom.xml
deleted file mode 100644
index e5ab046cdc0ae6ece6da29550f9df9fde7963bf1..0000000000000000000000000000000000000000
--- a/java/services/users/pom.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<parent>
-		<groupId>org.springframework.boot</groupId>
-		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>3.3.4</version>
-		<relativePath/> <!-- lookup parent from repository -->
-	</parent>
-	<groupId>com.uva</groupId>
-	<artifactId>usersService</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
-	<name>usersService</name>
-	<description>Users microservice</description>
-	<url/>
-	<licenses>
-		<license/>
-	</licenses>
-	<developers>
-		<developer/>
-	</developers>
-	<scm>
-		<connection/>
-		<developerConnection/>
-		<tag/>
-		<url/>
-	</scm>
-	<properties>
-		<java.version>17</java.version>
-	</properties>
-	<dependencies>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-jpa</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-rest</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>com.mysql</groupId>
-			<artifactId>mysql-connector-j</artifactId>
-			<scope>runtime</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-test</artifactId>
-			<scope>test</scope>
-		</dependency>
-	</dependencies>
-
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
-			</plugin>
-		</plugins>
-	</build>
-
-</project>
diff --git a/java/services/users/src/main/java/com/uva/users/Controllers/UserController.java b/java/services/users/src/main/java/com/uva/users/Controllers/UserController.java
deleted file mode 100644
index 30274d83e081b0d39b701e3c711b63b2e06ee5eb..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/users/Controllers/UserController.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.uva.users.Controllers;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.http.HttpMethod;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PatchMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.core.ParameterizedTypeReference;
-
-import com.uva.users.Models.UserStatus;
-import com.uva.users.Models.User;
-import com.uva.users.Repositories.UserRepository;
-
-@RestController
-@RequestMapping("users")
-@CrossOrigin(origins = "*")
-
-public class UserController {
-
-  private UserRepository userRepository;
-  @Autowired
-  private RestTemplate restTemplate;
-
-  @GetMapping
-  public List<User> getAllUsers() {
-    return userRepository.findAll();
-  }
-
-  @PostMapping
-  public User addUser(@RequestBody User user) {
-    user.setStatus(UserStatus.NO_BOOKINGS);
-    return userRepository.save(user);
-  }
-
-  @GetMapping("/{id}")
-  public User getUserById(@PathVariable int id) {
-    return userRepository.findById(id).orElseThrow();
-  }
-
-  @PutMapping("/{id}")
-  public User updateUserData(@PathVariable int id, @RequestBody Map<String, String> json) {
-    User target = userRepository.findById(id).orElseThrow();
-    if (!json.containsKey("name") || !json.containsKey("email")) {
-      throw new RuntimeException("Missing required fields");
-    }
-    target.setName(json.get("name"));
-    target.setEmail(json.get("email"));
-    return userRepository.save(target);
-  }
-
-  @PatchMapping("/{id}")
-  public User updateUserState(@PathVariable int id, @RequestBody Map<String, String> json) {
-    User target = userRepository.findById(id).orElseThrow();
-    String strStatus = json.get("status");
-    if (strStatus == null) {
-      throw new RuntimeException("Missing required fields");
-    }
-    UserStatus userStatus = UserStatus.valueOf(strStatus);
-
-    // Consultar el microservicio de booking
-    ResponseEntity<List<Map<String, Object>>> response = restTemplate.exchange(
-        "http://booking-service/users/{id}/bookings",
-        HttpMethod.GET,
-        null,
-        new ParameterizedTypeReference<List<Map<String, Object>>>() {},
-        id
-    );
-    List<Map<String, Object>> bookings = response.getBody();
-
-    boolean activeBookings = bookings.stream()
-        .anyMatch(booking -> LocalDate.parse((String) booking.get("endDate")).isAfter(LocalDate.now()));
-    boolean inactiveBookings = bookings.stream()
-        .anyMatch(booking -> LocalDate.parse((String) booking.get("startDate")).isBefore(LocalDate.now()));
-
-    switch (userStatus) {
-      case NO_BOOKINGS:
-        if (!bookings.isEmpty())
-          throw new IllegalArgumentException("Invalid State: The user has at least one booking");
-        break;
-      case WITH_ACTIVE_BOOKINGS:
-        if (bookings.isEmpty() || !activeBookings)
-          throw new IllegalArgumentException("Invalid State: The user doesn't have active bookings");
-        break;
-      case WITH_INACTIVE_BOOKINGS:
-        if (bookings.isEmpty() || !inactiveBookings)
-          throw new IllegalArgumentException("Invalid State: The user doesn't have inactive bookings");
-        break;
-      default:
-        break;
-    }
-    target.setStatus(userStatus);
-    return userRepository.save(target);
-  }
-
-  @DeleteMapping("/{id}")
-  public User deleteUser(@PathVariable Integer id) {
-    User target = userRepository.findById(id).orElseThrow();
-    userRepository.deleteById(id);
-    return target;
-  }
-
-  @GetMapping("/{id}/bookings")
-  public List<Map<String, Object>> getUserBookingsById(@PathVariable int id) {
-    // Llamada al microservicio de reservas
-    ResponseEntity<List<Map<String, Object>>> response = restTemplate.exchange(
-        "http://booking-service/users/{id}/bookings",
-        HttpMethod.GET,
-        null,
-        new ParameterizedTypeReference<List<Map<String, Object>>>() {},
-        id
-    );
-    return response.getBody();
-  }
-
-  @GetMapping(params = "email")
-  public ResponseEntity<User> getUserByEmail(@RequestParam String email) {
-    return userRepository.findByEmail(email)
-        .map(ResponseEntity::ok)
-        .orElse(ResponseEntity.noContent().build());
-}
-
-}
diff --git a/java/services/users/src/main/java/com/uva/users/Exceptions/InvalidRequestException.java b/java/services/users/src/main/java/com/uva/users/Exceptions/InvalidRequestException.java
deleted file mode 100644
index 7b2712bccf3907b24cbbf6e664e5250865bb8064..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/users/Exceptions/InvalidRequestException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.users.Exceptions;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class InvalidRequestException extends RuntimeException {
-    public InvalidRequestException(String message) {
-        super(message);
-    }
-}
diff --git a/java/services/users/src/main/java/com/uva/users/Models/User.java b/java/services/users/src/main/java/com/uva/users/Models/User.java
deleted file mode 100644
index 455ef0282362759424cba7a75a3385073de48e4e..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/users/Models/User.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.uva.users.Models;
-
-import jakarta.persistence.Basic;
-import jakarta.persistence.Entity;
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
-@Entity
-@Table(name = "users")
-public class User {
-  @Id
-  @GeneratedValue(strategy = GenerationType.IDENTITY)
-  @Basic(optional = false)
-  private int id;
-
-  @Basic(optional = false)
-  private String name;
-
-  @Basic(optional = false)
-  private String email;
-
-  @Basic(optional = false)
-  @Enumerated(EnumType.STRING)
-  private UserStatus status = UserStatus.NO_BOOKINGS;
-
-  @Basic (optional = false)
-  private String password;
-
-  public User() {
-  }
-
-  public User(int id, String name, String email, UserStatus status, String password) {
-    setId(id);
-    setName(name);
-    setEmail(email);
-    setStatus(status);
-    setPassword(password);
-  }
-
-  // Getters y setters
-  public int getId() {
-    return id;
-  }
-
-  public void setId(int id) {
-    this.id = id;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public String getEmail() {
-    return email;
-  }
-
-  public void setEmail(String email) {
-    this.email = email;
-  }
-
-  public UserStatus getStatus() {
-    return status;
-  }
-
-  public void setStatus(UserStatus status) {
-    this.status = status;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public void setPassword(String password) {
-    this.password = password;
-  }
-}
diff --git a/java/services/users/src/main/java/com/uva/users/UserServiceApplication.java b/java/services/users/src/main/java/com/uva/users/UserServiceApplication.java
deleted file mode 100644
index 842ddd66f511f1c766c963b9604924a60919993b..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/users/UserServiceApplication.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.users;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class UserServiceApplication {
-
-	public static void main(String[] args) {
-		SpringApplication.run(UserServiceApplication.class, args);
-	}
-
-}
diff --git a/java/services/users/src/main/java/com/uva/users/config/RestTemplateConfig.java b/java/services/users/src/main/java/com/uva/users/config/RestTemplateConfig.java
deleted file mode 100644
index 9343721935b419c627937c713f56b64f40d894d1..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/users/config/RestTemplateConfig.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.uva.users.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.client.RestTemplate;
-
-@Configuration
-public class RestTemplateConfig {
-
-    @Bean
-    public RestTemplate restTemplate() {
-        return new RestTemplate();
-    }
-}
diff --git a/java/services/users/src/main/resources/application.properties b/java/services/users/src/main/resources/application.properties
deleted file mode 100644
index f56d92d0392f20307e5c1cb9e27f16cfb2162ba2..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/resources/application.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-spring.application.name=userService
-server.port=8111
-spring.jpa.hibernate.ddl-auto=update
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
-spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/RoomsBooking?createDatabaseIfNotExist=true
-spring.datasource.username=user
-spring.datasource.password=password
-spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-
-# Usar esto para alternar entre las exposición del room repository ya que no es necesario su uso pero por defecto, al no cubrir su ruta, se expone
-# spring.data.rest.base-path=false
\ No newline at end of file
diff --git a/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java
deleted file mode 100644
index 3b50599492c36017391c0dcabd81573f123a809a..0000000000000000000000000000000000000000
--- a/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.roomBooking;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class RoomBookingApplicationTests {
-
-	@Test
-	void contextLoads() {
-	}
-
-}