diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index 48ca6fbb5d1debf221a15c1bc2606816109255fc..f5788453e7e148b54e4c11a1b5a5a4b6e028413b 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -20,7 +20,7 @@ lint:
   disabled:
     - git-diff-check
   enabled:
-    - checkov@3.2.336
+    - checkov@3.2.341
     - dotenv-linter@3.3.0
     - hadolint@2.12.1-beta
     - markdownlint@0.43.0
diff --git a/angular/RestClient/src/app/app.component.ts b/angular/RestClient/src/app/app.component.ts
index f6060eca2fe714c3b89bb6ee62c3e02b26f37a94..a1ed6618427b136f4c7574b3fa019fd416e7adf7 100644
--- a/angular/RestClient/src/app/app.component.ts
+++ b/angular/RestClient/src/app/app.component.ts
@@ -1,6 +1,6 @@
 import { Component } from '@angular/core';
 import { RouterOutlet } from '@angular/router';
-import { NavigationComponent } from './core/navigation/navigation.component';
+import { NavigationComponent } from '@shared';
 
 @Component({
   selector: 'app-root',
diff --git a/angular/RestClient/src/app/app.config.ts b/angular/RestClient/src/app/app.config.ts
index c0664f634af159df0208b1a877011ce66c1471ac..18eaee48c05caac28365f5076338fd28cc8cd20c 100644
--- a/angular/RestClient/src/app/app.config.ts
+++ b/angular/RestClient/src/app/app.config.ts
@@ -9,7 +9,7 @@ import {
 import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
 import { ReactiveFormsModule } from '@angular/forms'; // Added import for ReactiveFormsModule
 import { provideNativeDateAdapter } from '@angular/material/core';
-import { authRequest } from './security/auth.interceptor';
+import { authRequest } from '@core/interceptors';
 
 export const appConfig: ApplicationConfig = {
   providers: [
diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index 4be490fc5813f4e0bca3846bfd83e67c06ce0654..2853c5e2d788dcaa89454b0004ca0fcf1b86e8e0 100644
--- a/angular/RestClient/src/app/app.routes.ts
+++ b/angular/RestClient/src/app/app.routes.ts
@@ -1,177 +1,41 @@
-import { Route, Routes } from '@angular/router';
-import { HotelListComponent } from './core/features/hotel/hotel-list/hotel-list.component';
-import { BookingComponent } from './core/features/bookings/booking/booking.component';
-import { HotelRegisterComponent } from './core/features/hotel/hotel-register/hotel-register.component';
-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 { HotelListComponent } from './features/hotels/hotel-list/hotel-list.component';
+import { BookingComponent } from './features/bookings/booking/booking.component';
+import { HotelRegisterComponent } from './features/hotels/hotel-register/hotel-register.component';
+import { MainPageComponent } from './features/users/main-page/main-page.component';
+import { UserBookingListComponent } from './features/bookings/user-booking-list/user-booking-list.component';
+import { UserFormComponent } from './features/users/user-form/user-form.component';
 import { UnauthorizedComponent } from './page/unauthorized/unauthorized.component';
-import { rolGuard } from './security/rol.guard';
-import { UserRol, UserRolesArray } from './types';
-
-interface RouteData {
-  expectedRole: UserRol | UserRol[];
-}
-
-type AppRoute = Omit<Route, 'data'> & {
-  data?: RouteData;
-};
+import { AppRoute, UserRolesArray } from './core/models';
+import { rolGuard, rolGuardChild } from '@core/guards';
 
 export const routes: AppRoute[] = [
   // Auth
   {
-    path: 'login',
-    component: UserFormComponent,
-  },
-  {
-    path: 'register',
-    component: UserFormComponent,
+    path: '',
+    loadChildren: () => import('./features/auth').then((m) => m.AUTH_ROUTES),
   },
-
   // Hoteles
   {
-    path: 'hotels', // Ruta para la lista de hoteles
-    component: HotelListComponent,
-  },
-  {
-    path: 'hotels/register', // Registrar nuevo hotel
-    component: HotelRegisterComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'HOTEL_ADMIN' },
-  },
-  {
-    path: 'hotels/:id', // Hotel concreto
-    component: HotelRegisterComponent,
+    path: 'hotels',
+    loadChildren: () =>
+      import('./features/hotels').then((m) => m.HOTELS_ROUTES),
   },
-
   // Usuario
   {
-    path: 'me', // Main
-    canActivate: [rolGuard],
-    data: { expectedRole: UserRolesArray },
-    component: UserFormComponent,
-  },
-  {
-    path: 'me/edit', // Main
-    component: UserFormComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: UserRolesArray },
-  },
-  {
-    path: 'me/change-passwd', // Main
-    component: UserFormComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: UserRolesArray },
-  },
-  // Usuario HOTEL admin
-  {
-    path: 'me/hotels',
-    component: HotelListComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'HOTEL_ADMIN' },
-  },
-  {
-    path: 'me/hotels/:id',
-    component: HotelRegisterComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'HOTEL_ADMIN' },
-  },
-  // {
-  //   path: 'me/hotels/:id/bookings',
-  //   component: BookingListComponent,
-  // },
-  // {
-  //   path: 'me/hotels/:id/rooms/:id/bookings',
-  //   component: BookingListComponent,
-  // },
-
-  // Usuario Cliente
-  {
-    path: 'me/bookings',
-    component: UserBookingListComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'CLIENT' },
-  },
-  {
-    path: 'me/bookings/:id',
-    component: BookingComponent,
+    path: 'me',
     canActivate: [rolGuard],
-    data: { expectedRole: 'CLIENT' },
+    canActivateChild: [rolGuardChild],
+    loadChildren: () => import('./features/users').then((m) => m.USERS_ROUTES),
   },
-  {
-    path: 'me/bookings/new',
-    component: BookingComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'CLIENT' },
-  },
-
   // Administrador
   {
-    path: 'admin', // Main
-    component: UserFormComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'ADMIN' },
-  },
-  {
-    path: 'admin/users', // Main
-    component: MainPageComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'ADMIN' },
-  },
-  {
-    path: 'admin/users/:id', // Main
-    component: UserFormComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'ADMIN' },
-  },
-  {
-    path: 'admin/users/:id/edit', // Main
-    component: UserFormComponent,
+    path: 'admin',
     canActivate: [rolGuard],
+    canActivateChild: [rolGuardChild],
     data: { expectedRole: 'ADMIN' },
+    loadChildren: () => import('./features/admin').then((m) => m.ADMIN_ROUTES),
   },
-  {
-    path: 'admin/users/:id/change-passwd', // Main
-    component: UserFormComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'ADMIN' },
-  },
-  {
-    path: 'admin/users/:id/bookings',
-    component: UserBookingListComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'ADMIN' },
-  },
-  // {
-  //   path: 'admin/users/:id/bookings/:bookingId',
-  //   component: BookingComponent,
-  // },
-  {
-    path: 'admin/users/:id/hotels',
-    component: HotelListComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'ADMIN' },
-  },
-  {
-    path: 'admin/users/:userId/hotels/:id',
-    component: HotelRegisterComponent,
-    canActivate: [rolGuard],
-    data: { expectedRole: 'ADMIN' },
-  },
-  // {
-  //   path: 'admin/users/:userId/hotels/:id/bookings',
-  //   component: BookingListComponent,
-  //   canActivate: [rolGuard],
-  //   data: { expectedRole: 'ADMIN' },
-  // },
-  // {
-  //   path: 'admin/users/:userId/hotels/:hotelId/rooms/:id/bookings',
-  //   component: BookingListComponent,
-  //   canActivate: [rolGuard],
-  //   data: { expectedRole: 'ADMIN' },
-  // },
-
+  // Página no autorizada
   {
     path: 'unauthorized',
     component: UnauthorizedComponent,
diff --git a/angular/RestClient/src/app/core/guards/index.ts b/angular/RestClient/src/app/core/guards/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7c221e12c653c53b072a570f871bdbdc37d3909e
--- /dev/null
+++ b/angular/RestClient/src/app/core/guards/index.ts
@@ -0,0 +1 @@
+export * from './rol.guard';
diff --git a/angular/RestClient/src/app/security/rol.guard.spec.ts b/angular/RestClient/src/app/core/guards/rol.guard.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/security/rol.guard.spec.ts
rename to angular/RestClient/src/app/core/guards/rol.guard.spec.ts
diff --git a/angular/RestClient/src/app/core/guards/rol.guard.ts b/angular/RestClient/src/app/core/guards/rol.guard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..39aca9bb6fe82f1a6dc9abe6e7d92eb0bccb9944
--- /dev/null
+++ b/angular/RestClient/src/app/core/guards/rol.guard.ts
@@ -0,0 +1,78 @@
+import { inject } from '@angular/core';
+import {
+  ActivatedRouteSnapshot,
+  CanActivateChildFn,
+  CanActivateFn,
+  Router,
+} from '@angular/router';
+import { Session, UserRol } from '@core/models';
+import { SessionService } from '@core/services';
+
+import { map } from 'rxjs';
+
+/**
+ * Obtiene el rol de la ruta padre si el hijo no define uno.
+ * Navega hacia los ancestros buscando un rol especificado en `data`.
+ */
+function getInheritedRole(route: ActivatedRouteSnapshot): string | undefined {
+  let parent = route.parent; // Comenzar desde el padre inmediato
+  while (parent) {
+    if (parent.data && parent.data['rol']) {
+      return parent.data['rol']; // Retorna el primer rol encontrado
+    }
+    parent = parent.parent; // Continuar hacia arriba en el árbol
+  }
+  return undefined; // No se encontró un rol definido en los ancestros
+}
+
+function verifyRol(expectedRole: UserRol) {
+  const sessionService = inject(SessionService);
+  const router = inject(Router);
+  // Verifica si el usuario tiene sesión activa
+  const session = sessionService.isValid();
+
+  if (!session) {
+    console.log('no session');
+    router.navigate(['/login']);
+    return false;
+  }
+  return sessionService.getSession().pipe(
+    map((session: Session | null) => {
+      if (!session) return false;
+
+      if (
+        Array.isArray(expectedRole) &&
+        (expectedRole as UserRol[]).includes(session.rol)
+      ) {
+        console.log('Rol in Rol arry');
+        return true;
+      } else if (session.rol === expectedRole) {
+        console.log('Rol valido');
+        return true;
+      }
+      console.log('Unautorizado');
+
+      // Redirige si el usuario no tiene el rol necesario
+      router.navigate(['/unauthorized']);
+      return false;
+    })
+  );
+}
+
+export const rolGuard: CanActivateFn = (route, state) => {
+  // Obtén el rol esperado desde los datos de la ruta
+  const expectedRole = route.data?.['expectedRole'];
+  return verifyRol(expectedRole);
+};
+
+export const rolGuardChild: CanActivateChildFn = (childRoute, state) => {
+  // Obtener el rol de la ruta hija si está especificado y en caso
+  // de no especificarse se busca en el/los padres
+  let requiredRol = childRoute.data['rol'] ?? getInheritedRole(childRoute);
+
+  // Si no hay rol especificado se supone libre de verificación
+  if (!requiredRol) return true;
+
+  // Verificar si el usuario tiene el rol requerido
+  return verifyRol(requiredRol);
+};
diff --git a/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts b/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..50f38c8abbeb5059524cfd0077b10a09260936d7
--- /dev/null
+++ b/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts
@@ -0,0 +1,17 @@
+import { TestBed } from '@angular/core/testing';
+import { HttpInterceptorFn } from '@angular/common/http';
+
+import { authInterceptor } from './auth.interceptor';
+
+describe('authInterceptor', () => {
+  const interceptor: HttpInterceptorFn = (req, next) => 
+    TestBed.runInInjectionContext(() => authInterceptor(req, next));
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+  });
+
+  it('should be created', () => {
+    expect(interceptor).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/security/auth.interceptor.ts b/angular/RestClient/src/app/core/interceptors/auth.interceptor.ts
similarity index 88%
rename from angular/RestClient/src/app/security/auth.interceptor.ts
rename to angular/RestClient/src/app/core/interceptors/auth.interceptor.ts
index 4a3dadfdaa637c526d0beb436546a9117359f49f..11c9d68089278f997f5c0d4bc0360144f9cf1af9 100644
--- a/angular/RestClient/src/app/security/auth.interceptor.ts
+++ b/angular/RestClient/src/app/core/interceptors/auth.interceptor.ts
@@ -1,7 +1,6 @@
 import { HttpInterceptorFn } from '@angular/common/http';
 import { inject } from '@angular/core';
-import { LocalStorageService } from '../shared/local-storage.service';
-import { SessionService } from '../shared/session.service';
+import { SessionService } from '@core/services/session/session.service';
 
 const excluded = ['/login', '/register'];
 
diff --git a/angular/RestClient/src/app/core/interceptors/index.ts b/angular/RestClient/src/app/core/interceptors/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c59f58f0962748f55ad8510233508f2e2c9ad3e0
--- /dev/null
+++ b/angular/RestClient/src/app/core/interceptors/index.ts
@@ -0,0 +1 @@
+export * from './auth.interceptor';
diff --git a/angular/RestClient/src/app/types/Address.d.ts b/angular/RestClient/src/app/core/models/Address.interface.ts
similarity index 100%
rename from angular/RestClient/src/app/types/Address.d.ts
rename to angular/RestClient/src/app/core/models/Address.interface.ts
diff --git a/angular/RestClient/src/app/types/Booking.d.ts b/angular/RestClient/src/app/core/models/Booking.interface.ts
similarity index 57%
rename from angular/RestClient/src/app/types/Booking.d.ts
rename to angular/RestClient/src/app/core/models/Booking.interface.ts
index 797c8aafb11b15aff5ac7cb9a3f4b510d7628284..e18c7467f930fb9b2410fb8e377c1d3faa4cdf71 100644
--- a/angular/RestClient/src/app/types/Booking.d.ts
+++ b/angular/RestClient/src/app/core/models/Booking.interface.ts
@@ -1,5 +1,5 @@
-import { Room } from './Room';
-import { User } from './User';
+import { Room } from './Room.interface';
+import { User } from './User.interface';
 
 export interface Booking {
   id: number;
diff --git a/angular/RestClient/src/app/types/Hotel.d.ts b/angular/RestClient/src/app/core/models/Hotel.interface.ts
similarity index 51%
rename from angular/RestClient/src/app/types/Hotel.d.ts
rename to angular/RestClient/src/app/core/models/Hotel.interface.ts
index c4183aa7f7055c24016b6b4325038a16cdaca09c..38c70511fefaeb20d3ddde3baf3f469c42d7f79e 100644
--- a/angular/RestClient/src/app/types/Hotel.d.ts
+++ b/angular/RestClient/src/app/core/models/Hotel.interface.ts
@@ -1,5 +1,5 @@
-import { Address } from './Address';
-import { Room } from './Room';
+import { Address } from './Address.interface';
+import { Room } from './Room.interface';
 
 export interface Hotel {
   id: number;
diff --git a/angular/RestClient/src/app/types/Room.d.ts b/angular/RestClient/src/app/core/models/Room.interface.ts
similarity index 67%
rename from angular/RestClient/src/app/types/Room.d.ts
rename to angular/RestClient/src/app/core/models/Room.interface.ts
index 0c54fdcbfee2f4da7aa34f3727dd21421acbb048..a00b1e53c6ad8312f0f2edf78a99c891c4506716 100644
--- a/angular/RestClient/src/app/types/Room.d.ts
+++ b/angular/RestClient/src/app/core/models/Room.interface.ts
@@ -1,4 +1,7 @@
 export type RoomType = 'SINGLE' | 'DOUBLE' | 'SUITE';
+
+export const roomTypeArray: RoomType[] = ['SINGLE', 'DOUBLE', 'SUITE'];
+
 export interface Room {
   id: number;
   roomNumber: String;
diff --git a/angular/RestClient/src/app/core/models/Route.interface.ts b/angular/RestClient/src/app/core/models/Route.interface.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4653cda109a68fd4945cd14e81a1b65ccb5eef26
--- /dev/null
+++ b/angular/RestClient/src/app/core/models/Route.interface.ts
@@ -0,0 +1,10 @@
+import { Route } from '@angular/router';
+import { UserRol } from './User.interface';
+
+interface RouteData {
+  expectedRole: UserRol | UserRol[];
+}
+
+export type AppRoute = Omit<Route, 'data'> & {
+  data?: RouteData;
+};
diff --git a/angular/RestClient/src/app/types/Session.d.ts b/angular/RestClient/src/app/core/models/Session.interface.ts
similarity index 62%
rename from angular/RestClient/src/app/types/Session.d.ts
rename to angular/RestClient/src/app/core/models/Session.interface.ts
index 4dd1f742866d586be8be2ac02487d23ede92a486..59c7781b33b4275813576b9620cc8c80657c6042 100644
--- a/angular/RestClient/src/app/types/Session.d.ts
+++ b/angular/RestClient/src/app/core/models/Session.interface.ts
@@ -1,3 +1,5 @@
+import { UserRol } from './User.interface';
+
 export interface Session {
   id: number;
   name: string;
@@ -5,7 +7,7 @@ export interface Session {
   rol: UserRol;
 }
 
-interface PersistenToken {
+export interface PersistenToken {
   token: string;
   session?: Session;
 }
diff --git a/angular/RestClient/src/app/types/User.d.ts b/angular/RestClient/src/app/core/models/User.interface.ts
similarity index 86%
rename from angular/RestClient/src/app/types/User.d.ts
rename to angular/RestClient/src/app/core/models/User.interface.ts
index 277f806a74fb1b2f854d733cc10acca67f18b840..3854af0d5782e5fd5ff36412f94bd73c998b50c3 100644
--- a/angular/RestClient/src/app/types/User.d.ts
+++ b/angular/RestClient/src/app/core/models/User.interface.ts
@@ -15,6 +15,7 @@ export interface HotelAdmin extends User {
 }
 
 export type UserRol = 'ADMIN' | 'CLIENT' | 'HOTEL_ADMIN';
+export const UserRolesArray: UserRol[] = ['CLIENT', 'HOTEL_ADMIN', 'ADMIN'];
 
 export type UserStateFilter = 'All' | UserState;
 
diff --git a/angular/RestClient/src/app/core/models/index.ts b/angular/RestClient/src/app/core/models/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..311b36b9fe22a4aa133d6cf0ec105a301eb89bd6
--- /dev/null
+++ b/angular/RestClient/src/app/core/models/index.ts
@@ -0,0 +1,9 @@
+export * from './User.interface';
+export * from './Address.interface';
+export * from './Hotel.interface';
+export * from './Room.interface';
+export * from './Room.interface';
+export * from './Booking.interface';
+export * from './User.interface';
+export * from './Session.interface';
+export * from './Route.interface';
diff --git a/angular/RestClient/src/app/shared/auth-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts
similarity index 86%
rename from angular/RestClient/src/app/shared/auth-client.service.spec.ts
rename to angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts
index 718c264fe9fa26ade0a95ea726d68cf899584f1d..74e8f4811bfa8256bdccee865e2b86389b9c25f5 100644
--- a/angular/RestClient/src/app/shared/auth-client.service.spec.ts
+++ b/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts
@@ -1,9 +1,11 @@
 import { TestBed } from '@angular/core/testing';
 
 import { AuthClientService } from './auth-client.service';
+import { Session } from '@core/models';
 
 describe('AuthClientService', () => {
   let service: AuthClientService;
+  let s: Session;
 
   beforeEach(() => {
     TestBed.configureTestingModule({});
diff --git a/angular/RestClient/src/app/shared/auth-client.service.ts b/angular/RestClient/src/app/core/services/api/auth/auth-client.service.ts
similarity index 94%
rename from angular/RestClient/src/app/shared/auth-client.service.ts
rename to angular/RestClient/src/app/core/services/api/auth/auth-client.service.ts
index 99d3ebbfc0c91cc88ba2f4266cd1f895ccbfebd9..b2b499bd6777e4279bea462a654c645225126a6e 100644
--- a/angular/RestClient/src/app/shared/auth-client.service.ts
+++ b/angular/RestClient/src/app/core/services/api/auth/auth-client.service.ts
@@ -1,5 +1,5 @@
 import { Injectable } from '@angular/core';
-import { environment } from '../../environments/environment';
+import { environment } from '../../../../../environments/environment';
 import { HttpClient } from '@angular/common/http';
 
 @Injectable({
diff --git a/angular/RestClient/src/app/shared/booking-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/shared/booking-client.service.spec.ts
rename to angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts
diff --git a/angular/RestClient/src/app/shared/booking-client.service.ts b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts
similarity index 87%
rename from angular/RestClient/src/app/shared/booking-client.service.ts
rename to angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts
index a15867105f00cf0bd6ea093a4a64bebbb3fd048f..e5046766faeb5e6998ba18683852f0aa4046ea6f 100644
--- a/angular/RestClient/src/app/shared/booking-client.service.ts
+++ b/angular/RestClient/src/app/core/services/api/bookings/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 '../../../models/Booking.interface'; // Ajusta la ruta a tu modelo Booking
 
 @Injectable({
   providedIn: 'root',
diff --git a/angular/RestClient/src/app/shared/hotel-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/shared/hotel-client.service.spec.ts
rename to angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts
diff --git a/angular/RestClient/src/app/shared/hotel-client.service.ts b/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.ts
similarity index 84%
rename from angular/RestClient/src/app/shared/hotel-client.service.ts
rename to angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.ts
index 5c50231651d1e0bc61b036e3e1220d468009a4f8..5b5336c075d5e77346631fea7aea5ee766ef0d4c 100644
--- a/angular/RestClient/src/app/shared/hotel-client.service.ts
+++ b/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.ts
@@ -1,8 +1,8 @@
 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 { SessionService } from './session.service';
+import { Hotel, Room } from '../../../models';
+import { SessionService } from '../../session/session.service';
 import { catchError, map, switchMap, throwError } from 'rxjs';
 
 @Injectable({
@@ -28,13 +28,15 @@ export class HotelClientService {
     return this.http.get<Hotel[]>(url, { params: { start, end } });
   }
 
-  getAllHotelsByUser(userId:number, startDate?: Date, endDate?: Date) {
+  getAllHotelsByUser(userId: number, startDate?: Date, endDate?: Date) {
     const url = `${this.URI}`;
     if (!startDate || !endDate)
-      return this.http.get<Hotel[]>(url, { params: { managerId:userId } });
+      return this.http.get<Hotel[]>(url, { params: { managerId: userId } });
     const start = new Date(startDate).toISOString().split('T')[0];
     const end = new Date(endDate).toISOString().split('T')[0];
-    return this.http.get<Hotel[]>(url, { params: { managerId:userId, start, end } });
+    return this.http.get<Hotel[]>(url, {
+      params: { managerId: userId, start, end },
+    });
   }
 
   deleteHotel(id: number) {
diff --git a/angular/RestClient/src/app/shared/user-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/shared/user-client.service.spec.ts
rename to angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts
diff --git a/angular/RestClient/src/app/shared/user-client.service.ts b/angular/RestClient/src/app/core/services/api/users/user-client.service.ts
similarity index 87%
rename from angular/RestClient/src/app/shared/user-client.service.ts
rename to angular/RestClient/src/app/core/services/api/users/user-client.service.ts
index 63575df4f440973090cde151f50137fb002b9d5d..ec9e5d7d4222c7152195c7ed9f4e7521dab1e865 100644
--- a/angular/RestClient/src/app/shared/user-client.service.ts
+++ b/angular/RestClient/src/app/core/services/api/users/user-client.service.ts
@@ -1,8 +1,8 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
-import { environment } from '../../environments/environment';
-import { Client, Session, User, UserState } from '../types';
-import { SessionService } from './session.service';
+import { environment } from '../../../../../environments/environment';
+import { Client, Session, User, UserState } from '../../../models';
+import { SessionService } from '../../session/session.service';
 import { tap } from 'rxjs';
 
 @Injectable({
diff --git a/angular/RestClient/src/app/core/services/index.ts b/angular/RestClient/src/app/core/services/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..deceec994328a11a1cff59c7492ee2cfca98d087
--- /dev/null
+++ b/angular/RestClient/src/app/core/services/index.ts
@@ -0,0 +1,6 @@
+export * from './api/auth/auth-client.service';
+export * from './api/bookings/booking-client.service';
+export * from './api/hotels/hotel-client.service';
+export * from './api/users/user-client.service';
+export * from './session/session.service';
+export * from './storage/local-storage.service';
diff --git a/angular/RestClient/src/app/shared/session.service.spec.ts b/angular/RestClient/src/app/core/services/session/session.service.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/shared/session.service.spec.ts
rename to angular/RestClient/src/app/core/services/session/session.service.spec.ts
diff --git a/angular/RestClient/src/app/shared/session.service.ts b/angular/RestClient/src/app/core/services/session/session.service.ts
similarity index 95%
rename from angular/RestClient/src/app/shared/session.service.ts
rename to angular/RestClient/src/app/core/services/session/session.service.ts
index ea460cdfac612b165b7f944967472da25f7a6cca..743250250b2b302a5cc7fe2f491debf70c7145fb 100644
--- a/angular/RestClient/src/app/shared/session.service.ts
+++ b/angular/RestClient/src/app/core/services/session/session.service.ts
@@ -1,10 +1,10 @@
 import { Injectable } from '@angular/core';
-import { LocalStorageService } from './local-storage.service';
-import { PersistenToken, Session, User, UserRol } from '../types';
+import { LocalStorageService } from '../storage/local-storage.service';
+import { PersistenToken, Session, UserRol } from '../../models';
 import { BehaviorSubject, Observable, throwError } from 'rxjs';
 import { catchError, map, tap } from 'rxjs/operators';
 import { jwtDecode } from 'jwt-decode';
-import { AuthClientService } from './auth-client.service';
+import { AuthClientService } from '../api/auth/auth-client.service';
 import { Router } from '@angular/router';
 
 interface JWTDecoded {
diff --git a/angular/RestClient/src/app/shared/local-storage.service.spec.ts b/angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/shared/local-storage.service.spec.ts
rename to angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts
diff --git a/angular/RestClient/src/app/shared/local-storage.service.ts b/angular/RestClient/src/app/core/services/storage/local-storage.service.ts
similarity index 100%
rename from angular/RestClient/src/app/shared/local-storage.service.ts
rename to angular/RestClient/src/app/core/services/storage/local-storage.service.ts
diff --git a/angular/RestClient/src/app/features/admin/index.ts b/angular/RestClient/src/app/features/admin/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..75585f85e1a443e22e77ca151df63981df56b2c4
--- /dev/null
+++ b/angular/RestClient/src/app/features/admin/index.ts
@@ -0,0 +1 @@
+export * from '../users/admin.routes';
diff --git a/angular/RestClient/src/app/features/auth/auth.routes.ts b/angular/RestClient/src/app/features/auth/auth.routes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..86d8183271d8f149246cffcce0128561545a52cb
--- /dev/null
+++ b/angular/RestClient/src/app/features/auth/auth.routes.ts
@@ -0,0 +1,13 @@
+import { AppRoute } from '@core/models';
+import { UserFormComponent } from 'app/features/users';
+
+export const AUTH_ROUTES: AppRoute[] = [
+  {
+    path: 'login',
+    component: UserFormComponent,
+  },
+  {
+    path: 'register',
+    component: UserFormComponent,
+  },
+];
diff --git a/angular/RestClient/src/app/features/auth/index.ts b/angular/RestClient/src/app/features/auth/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bb519ed37118e740f94bc05f1a56483aa0cfbe95
--- /dev/null
+++ b/angular/RestClient/src/app/features/auth/index.ts
@@ -0,0 +1,3 @@
+export * from './auth.routes';
+export * from './login/login.component';
+export * from './register/register.component';
diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.css b/angular/RestClient/src/app/features/auth/login/login.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/auth/login/login.component.css
rename to angular/RestClient/src/app/features/auth/login/login.component.css
diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.html b/angular/RestClient/src/app/features/auth/login/login.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/auth/login/login.component.html
rename to angular/RestClient/src/app/features/auth/login/login.component.html
diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.spec.ts b/angular/RestClient/src/app/features/auth/login/login.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/auth/login/login.component.spec.ts
rename to angular/RestClient/src/app/features/auth/login/login.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.ts b/angular/RestClient/src/app/features/auth/login/login.component.ts
similarity index 91%
rename from angular/RestClient/src/app/core/features/auth/login/login.component.ts
rename to angular/RestClient/src/app/features/auth/login/login.component.ts
index d3bed7a4132fa619c110a0ebd74c3e8225e16216..c28e44d79ac016d6848e77571201b86e14c89031 100644
--- a/angular/RestClient/src/app/core/features/auth/login/login.component.ts
+++ b/angular/RestClient/src/app/features/auth/login/login.component.ts
@@ -12,8 +12,8 @@ import { MatFormFieldModule } from '@angular/material/form-field';
 import { MatSelectModule } from '@angular/material/select';
 import { MatSlideToggleModule } from '@angular/material/slide-toggle';
 import { Router } from '@angular/router';
-import { SessionService } from '../../../../shared/session.service';
-import { UserRol, UserRolesArray } from '../../../../types';
+import { SessionService } from '../../../core/services/session/session.service';
+import { UserRol, UserRolesArray } from '../../../core/models';
 
 @Component({
   standalone: true,
diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.css b/angular/RestClient/src/app/features/auth/register/register.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/auth/register/register.component.css
rename to angular/RestClient/src/app/features/auth/register/register.component.css
diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.html b/angular/RestClient/src/app/features/auth/register/register.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/auth/register/register.component.html
rename to angular/RestClient/src/app/features/auth/register/register.component.html
diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.spec.ts b/angular/RestClient/src/app/features/auth/register/register.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/auth/register/register.component.spec.ts
rename to angular/RestClient/src/app/features/auth/register/register.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.ts b/angular/RestClient/src/app/features/auth/register/register.component.ts
similarity index 91%
rename from angular/RestClient/src/app/core/features/auth/register/register.component.ts
rename to angular/RestClient/src/app/features/auth/register/register.component.ts
index e594c19b132e84967d2509e2c3e4a5053a66f048..62d97d6b8697d5e3dbf001929c5be12bbf70cdee 100644
--- a/angular/RestClient/src/app/core/features/auth/register/register.component.ts
+++ b/angular/RestClient/src/app/features/auth/register/register.component.ts
@@ -12,8 +12,8 @@ import { MatFormFieldModule } from '@angular/material/form-field';
 import { MatSelectModule } from '@angular/material/select';
 import { MatSlideToggleModule } from '@angular/material/slide-toggle';
 import { Router } from '@angular/router';
-import { AuthClientService } from '../../../../shared/auth-client.service';
-import { SessionService } from '../../../../shared/session.service';
+import { AuthClientService } from '../../../core/services/api/auth/auth-client.service';
+import { SessionService } from '../../../core/services/session/session.service';
 
 // TODO agregar selector de roles
 
@@ -60,7 +60,7 @@ export class RegisterComponent {
       this.authClient.register(name, email, password).subscribe({
         next: (res: any) => {
           console.log({ res });
-          this.sessionManager.login(res);
+          this.sessionManager.login(res, '');
           alert('Usuario registrado con éxito.');
           this.router.navigate(['/']); // Redirigir al login
         },
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.css b/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.css
rename to angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.css
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.html b/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.html
rename to angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.html
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.spec.ts b/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.spec.ts
rename to angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts b/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.ts
similarity index 91%
rename from angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts
rename to angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.ts
index 0e573456823b7cc0cbb4e098075f835141678a21..545cfce5222e6772780f2a51cec5f9b64cd8c894 100644
--- a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts
+++ b/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.ts
@@ -7,12 +7,12 @@ 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 '../../../core/models';
 import { Router } from '@angular/router';
 import { MatCardModule } from '@angular/material/card';
 import { MatChipsModule } from '@angular/material/chips';
-import { LocalStorageService } from '../../../../shared/local-storage.service';
-import { HotelClientService } from '../../../../shared/hotel-client.service';
+import { LocalStorageService } from '../../../core/services/storage/local-storage.service';
+import { HotelClientService } from '../../../core/services/api/hotels/hotel-client.service';
 
 type SelectableRoomType = 'All' | RoomType;
 const selectableRoomTypeArray: SelectableRoomType[] = ['All', ...roomTypeArray];
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.css b/angular/RestClient/src/app/features/bookings/booking/booking.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/bookings/booking/booking.component.css
rename to angular/RestClient/src/app/features/bookings/booking/booking.component.css
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.html b/angular/RestClient/src/app/features/bookings/booking/booking.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/bookings/booking/booking.component.html
rename to angular/RestClient/src/app/features/bookings/booking/booking.component.html
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.spec.ts b/angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/bookings/booking/booking.component.spec.ts
rename to angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts b/angular/RestClient/src/app/features/bookings/booking/booking.component.ts
similarity index 89%
rename from angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts
rename to angular/RestClient/src/app/features/bookings/booking/booking.component.ts
index 6691027e241bff16a2b25fb71e23a1309ec1929e..f37e6576c13158c3bcdcca482c179c82b03904bb 100644
--- a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts
+++ b/angular/RestClient/src/app/features/bookings/booking/booking.component.ts
@@ -7,11 +7,11 @@ import {
 } from '@angular/forms';
 
 import { ActivatedRoute, Router } from '@angular/router';
-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';
-import { SessionService } from '../../../../shared/session.service';
+import { Booking, User } from '../../../core/models';
+import { LocalStorageService } from '../../../core/services/storage/local-storage.service';
+import { BookingClientService } from '../../../core/services/api/bookings/booking-client.service';
+import { UserClientService } from '../../../core/services/api/users/user-client.service';
+import { SessionService } from '../../../core/services/session/session.service';
 
 type communication = {
   roomId: number;
diff --git a/angular/RestClient/src/app/features/bookings/bookings.routes.ts b/angular/RestClient/src/app/features/bookings/bookings.routes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a35688a9184f63633ed96f4e1a92d2d7ae402e3e
--- /dev/null
+++ b/angular/RestClient/src/app/features/bookings/bookings.routes.ts
@@ -0,0 +1,22 @@
+import { AppRoute } from '@core/models';
+import { BookingComponent } from './booking/booking.component';
+import { UserBookingListComponent } from './user-booking-list/user-booking-list.component';
+
+export const BOOKINGS_ROUTES: AppRoute[] = [];
+export const CLIENT_BOOKINGS_ROUTES: AppRoute[] = [
+  {
+    path: '',
+    component: UserBookingListComponent,
+    data: { expectedRole: 'CLIENT' },
+  },
+  {
+    path: ':id',
+    component: BookingComponent,
+    data: { expectedRole: 'CLIENT' },
+  },
+  {
+    path: 'new',
+    component: BookingComponent,
+    data: { expectedRole: 'CLIENT' },
+  },
+];
diff --git a/angular/RestClient/src/app/features/bookings/index.ts b/angular/RestClient/src/app/features/bookings/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aa2b48a8a5e51016f6fb70658f3bbe0ab78aad8a
--- /dev/null
+++ b/angular/RestClient/src/app/features/bookings/index.ts
@@ -0,0 +1,4 @@
+export * from './bookings.routes';
+export * from './booking/booking.component';
+export * from './booking-list/booking-list.component';
+export * from './user-booking-list/user-booking-list.component';
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.css b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.css
rename to angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.css
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.html b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.html
rename to angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.spec.ts b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.spec.ts
rename to angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts
similarity index 92%
rename from angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts
rename to angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts
index f5ca26c52374160a4a16fe933a03cec8a8fed823..a76d5b38b9face0358016a6088f8c4e8bf8349d1 100644
--- a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts
+++ b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts
@@ -1,12 +1,12 @@
 import { Component } from '@angular/core';
 
-import { Booking, User } from '../../../../types';
+import { Booking, User } from '../../../core/models';
 import { ActivatedRoute, RouterModule } from '@angular/router';
 import { CommonModule } from '@angular/common';
 import { FormsModule } from '@angular/forms';
-import { UserClientService } from '../../../../shared/user-client.service';
-import { BookingClientService } from '../../../../shared/booking-client.service';
-import { SessionService } from '../../../../shared/session.service';
+import { UserClientService } from '../../../core/services/api/users/user-client.service';
+import { BookingClientService } from '../../../core/services/api/bookings/booking-client.service';
+import { SessionService } from '../../../core/services/session/session.service';
 import { Observable } from 'rxjs';
 
 type state = 'all' | 'active' | 'inactive';
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.css b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.css
rename to angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.css
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.html b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.html
rename to angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.html
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.spec.ts b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.spec.ts
rename to angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts
similarity index 90%
rename from angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts
rename to angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts
index 1b6e34d096b35b4ef53be036aa767258592dee54..4cf5d5c40b4d5931eb994a05befe425ec0d20fc1 100644
--- a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts
+++ b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts
@@ -1,6 +1,6 @@
 import { Component, NgModule } from '@angular/core';
 import { RouterModule, Router, ActivatedRoute, Data } from '@angular/router';
-import { Hotel, Room, RoomType, roomTypeArray } from '../../../../types';
+import { Hotel, Room, RoomType, roomTypeArray } from '../../../core/models';
 import {
   MatAccordion,
   MatExpansionPanel,
@@ -15,16 +15,16 @@ import {
   NgbAccordionModule,
   NgbDatepickerModule,
 } from '@ng-bootstrap/ng-bootstrap';
-import { HotelClientService } from '../../../../shared/hotel-client.service';
+import { HotelClientService } from '../../../core/services/api/hotels/hotel-client.service';
 import { MatCardModule } from '@angular/material/card';
 import { MatIconModule } from '@angular/material/icon';
 import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
 import { MatFormFieldModule } from '@angular/material/form-field';
 import { MatDatepickerModule } from '@angular/material/datepicker';
 import { MatSelectModule } from '@angular/material/select';
-import { LocalStorageService } from '../../../../shared/local-storage.service';
-import { SessionService } from '../../../../shared/session.service';
-import { getBasePath } from '../../../../utils/utils';
+import { LocalStorageService } from '../../../core/services/storage/local-storage.service';
+import { SessionService } from '../../../core/services/session/session.service';
+import { getBasePath } from '../../../utils/utils';
 
 type SelectableRoomType = 'All' | RoomType;
 const selectableRoomTypeArray: SelectableRoomType[] = ['All', ...roomTypeArray];
@@ -66,7 +66,7 @@ export class HotelListComponent {
   roomTypes = selectableRoomTypeArray;
   rooms: Room[] = [];
   trateRooms: Room[] = [];
-  userId = 0
+  userId = 0;
 
   constructor(
     private fb: FormBuilder,
@@ -76,8 +76,8 @@ export class HotelListComponent {
     private storage: LocalStorageService,
     private sessionService: SessionService
   ) {
-    const isHotelManger = this.route.snapshot.url[0].path === 'me'
-    const isAdmin = this.route.snapshot.url[0].path === 'admin'
+    const isHotelManger = this.route.snapshot.url[0].path === 'me';
+    const isAdmin = this.route.snapshot.url[0].path === 'admin';
     this.isManaging = isHotelManger || isAdmin;
     const today = new Date();
 
@@ -93,7 +93,7 @@ export class HotelListComponent {
       next: (session) => {
         if (session && session.rol !== 'CLIENT') {
           this.isEditing = true;
-          this.userId = isHotelManger 
+          this.userId = isHotelManger
             ? session.id
             : Number(this.route.snapshot.paramMap.get('id'));
         }
@@ -146,11 +146,11 @@ export class HotelListComponent {
 
   getHotels() {
     const { start, end } = this.dateRangeForm.value.dateRange;
-    
+
     const observable = this.isManaging
       ? this.hotelClient.getAllHotelsByUser(this.userId, start, end)
-      : this.hotelClient.getAllHotels(start, end)
-    console.log({...this})
+      : this.hotelClient.getAllHotels(start, end);
+    console.log({ ...this });
     observable.subscribe({
       next: (resp) => {
         if (!!resp && (resp as never[]).length >= 0) {
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.css b/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.css
rename to angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.css
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.html b/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.html
rename to angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.html
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.spec.ts b/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.spec.ts
rename to angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts b/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.ts
similarity index 96%
rename from angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts
rename to angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.ts
index 9408ea3e1082fb50c4277a6912870e6472979518..598619033cb3f2f6633021c40770e90e5ce722ab 100644
--- a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts
+++ b/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.ts
@@ -13,9 +13,9 @@ 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 '../../../core/models';
 import { ActivatedRoute, Router } from '@angular/router';
-import { HotelClientService } from '../../../../shared/hotel-client.service';
+import { HotelClientService } from '../../../core/services/api/hotels/hotel-client.service';
 import { MatIconModule } from '@angular/material/icon';
 
 const emptyRoom: Room = {
diff --git a/angular/RestClient/src/app/features/hotels/hotels.routes.ts b/angular/RestClient/src/app/features/hotels/hotels.routes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9e000411a9680f7e8c0e8242d2f819e41bc959d6
--- /dev/null
+++ b/angular/RestClient/src/app/features/hotels/hotels.routes.ts
@@ -0,0 +1,45 @@
+import { AppRoute } from '@core/models';
+import { HotelRegisterComponent } from './hotel-register/hotel-register.component';
+import { HotelListComponent } from './hotel-list/hotel-list.component';
+import { rolGuard } from '@core/guards';
+
+export const HOTELS_ROUTES: AppRoute[] = [
+  {
+    path: '', // Ruta para la lista de hoteles
+    component: HotelListComponent,
+  },
+  {
+    path: 'register', // Registrar nuevo hotel
+    component: HotelRegisterComponent,
+    canActivate: [rolGuard],
+    data: { expectedRole: 'HOTEL_ADMIN' },
+  },
+  {
+    path: ':id', // Hotel concreto
+    component: HotelRegisterComponent,
+  },
+];
+
+export const MANAGERS_ROUTES: AppRoute[] = [
+  {
+    path: 'hotels',
+    children: [
+      {
+        path: '',
+        component: HotelListComponent,
+      },
+      {
+        path: ':id',
+        component: HotelRegisterComponent,
+      },
+      // {
+      //   path: ':id/bookings',
+      //   component: BookingListComponent,
+      // },
+      // {
+      //   path: ':id/rooms/:id/bookings',
+      //   component: BookingListComponent,
+      // },
+    ],
+  },
+];
diff --git a/angular/RestClient/src/app/features/hotels/index.ts b/angular/RestClient/src/app/features/hotels/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3af2b5ac86e2a4b41ca3f1e5b79cc989999238b2
--- /dev/null
+++ b/angular/RestClient/src/app/features/hotels/index.ts
@@ -0,0 +1,3 @@
+export * from './hotels.routes';
+export * from './hotel-list/hotel-list.component';
+export * from './hotel-register/hotel-register.component';
diff --git a/angular/RestClient/src/app/features/users/admin.routes.ts b/angular/RestClient/src/app/features/users/admin.routes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ff360470360e7b4b7d1d88192cf6cc1275500a8c
--- /dev/null
+++ b/angular/RestClient/src/app/features/users/admin.routes.ts
@@ -0,0 +1,46 @@
+import { AppRoute } from '@core/models';
+import { MainPageComponent } from 'app/features/users/main-page/main-page.component';
+import { UserFormComponent } from 'app/features/users/user-form/user-form.component';
+import { USERS_ROUTES } from 'app/features/users/users.routes';
+
+function getRoutesWithoutRol(routes: AppRoute[]) {
+  return routes.map((r) => {
+    if (r.data?.expectedRole) {
+      const { data, ...rest } = r;
+      return { ...rest };
+    }
+    return r;
+  });
+}
+
+export const ADMIN_ROUTES: AppRoute[] = [
+  {
+    path: '', // Main
+    component: UserFormComponent,
+  },
+  {
+    path: 'users',
+    children: [
+      {
+        path: '',
+        component: MainPageComponent,
+      },
+      {
+        path: ':id',
+        children: getRoutesWithoutRol(USERS_ROUTES),
+      },
+    ],
+  },
+  // {
+  //   path: 'users/:id/bookings/:bookingId',
+  //   component: BookingComponent,
+  // },
+  // {
+  //   path: 'users/:userId/hotels/:id/bookings',
+  //   component: BookingListComponent,
+  // },
+  // {
+  //   path: 'users/:userId/hotels/:hotelId/rooms/:id/bookings',
+  //   component: BookingListComponent,
+  // },
+];
diff --git a/angular/RestClient/src/app/features/users/index.ts b/angular/RestClient/src/app/features/users/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..baccb6244faa93ab6973fb42ef34ffd14eee9bc5
--- /dev/null
+++ b/angular/RestClient/src/app/features/users/index.ts
@@ -0,0 +1,3 @@
+export * from './users.routes';
+export * from './main-page/main-page.component';
+export * from './user-form/user-form.component';
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.css b/angular/RestClient/src/app/features/users/main-page/main-page.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/main-page/main-page.component.css
rename to angular/RestClient/src/app/features/users/main-page/main-page.component.css
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.html b/angular/RestClient/src/app/features/users/main-page/main-page.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/main-page/main-page.component.html
rename to angular/RestClient/src/app/features/users/main-page/main-page.component.html
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.spec.ts b/angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/main-page/main-page.component.spec.ts
rename to angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts b/angular/RestClient/src/app/features/users/main-page/main-page.component.ts
similarity index 90%
rename from angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts
rename to angular/RestClient/src/app/features/users/main-page/main-page.component.ts
index 09770a81445c949b6754000aeb014d66933e95c1..aaeee74453a7d72a3d51759987084aaab75fcf7c 100644
--- a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts
+++ b/angular/RestClient/src/app/features/users/main-page/main-page.component.ts
@@ -1,10 +1,10 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
-import { Client, User, UserStateFilter } from '../../../../types';
+import { Client, User, UserStateFilter } from '../../../core/models';
 import { FormsModule } from '@angular/forms';
 import { CommonModule } from '@angular/common';
 import { Router, RouterModule } from '@angular/router';
-import { UserClientService } from '../../../../shared/user-client.service';
-import { users } from '../../../../../mocks/users'; // Renombrado para claridad
+import { UserClientService } from '../../../core/services/api/users/user-client.service';
+import { users } from '../../../../mocks/users'; // Renombrado para claridad
 import { MatTableDataSource, MatTableModule } from '@angular/material/table';
 import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
 import { MatCardModule } from '@angular/material/card';
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.css b/angular/RestClient/src/app/features/users/user-form/user-form.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/user-form/user-form.component.css
rename to angular/RestClient/src/app/features/users/user-form/user-form.component.css
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.html b/angular/RestClient/src/app/features/users/user-form/user-form.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/features/user/user-form/user-form.component.html
rename to angular/RestClient/src/app/features/users/user-form/user-form.component.html
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.spec.ts b/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts
similarity index 87%
rename from angular/RestClient/src/app/core/features/user/user-form/user-form.component.spec.ts
rename to angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts
index 292f234075dbcba5482794cf23e4a231e666ba17..b2c1c438bf3079058be1e1c81ec8f81130cc75c8 100644
--- a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.spec.ts
+++ b/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts
@@ -2,7 +2,7 @@ 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 { UserClientService } from '../../../core/services/api/users/user-client.service';
 import { of } from 'rxjs';
 
 describe('UserFormComponent', () => {
@@ -31,8 +31,12 @@ describe('UserFormComponent', () => {
       })
     );
 
-    spyOn(userService, 'updateUser').and.returnValue(of(new HttpResponse({ body: 'User updated successfully' })));
-    spyOn(userService, 'updatePassword').and.returnValue(of(new HttpResponse({ body: 'Password updated successfully' })));
+    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();
   });
diff --git a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.ts b/angular/RestClient/src/app/features/users/user-form/user-form.component.ts
similarity index 96%
rename from angular/RestClient/src/app/core/features/user/user-form/user-form.component.ts
rename to angular/RestClient/src/app/features/users/user-form/user-form.component.ts
index 1c6d272d01c5a9b899b1c77a84773fe47c43c7bb..c57800fc59228402d653658462be49b380d40be3 100644
--- a/angular/RestClient/src/app/core/features/user/user-form/user-form.component.ts
+++ b/angular/RestClient/src/app/features/users/user-form/user-form.component.ts
@@ -6,18 +6,18 @@ import {
   ReactiveFormsModule,
   FormsModule,
 } from '@angular/forms';
-import { UserClientService } from '../../../../shared/user-client.service';
+import { UserClientService } from '../../../core/services/api/users/user-client.service';
 import { ActivatedRoute, Router, RouterModule } from '@angular/router';
 import { MatCardModule } from '@angular/material/card';
 import { MatInputModule } from '@angular/material/input';
 import { MatFormFieldModule } from '@angular/material/form-field';
 import { MatSlideToggleModule } from '@angular/material/slide-toggle';
-import { SessionService } from '../../../../shared/session.service';
-import { Session, UserRol, UserRolesArray } from '../../../../types';
+import { SessionService } from '../../../core/services/session/session.service';
+import { Session, UserRol, UserRolesArray } from '../../../core/models';
 import { MatSelectModule } from '@angular/material/select';
 import { Observable } from 'rxjs';
-import { getBasePath } from '../../../../utils/utils';
-import { environment } from '../../../../../environments/environment';
+import { getBasePath } from '../../../utils/utils';
+import { environment } from '../../../../environments/environment';
 
 type EditMode =
   | 'Login'
diff --git a/angular/RestClient/src/app/features/users/users.routes.ts b/angular/RestClient/src/app/features/users/users.routes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..84c240ff1e34363caf5c9d69c643b30a9ccb38ef
--- /dev/null
+++ b/angular/RestClient/src/app/features/users/users.routes.ts
@@ -0,0 +1,35 @@
+import { AppRoute, UserRolesArray } from '@core/models';
+import { UserFormComponent } from './user-form/user-form.component';
+
+export const USERS_ROUTES: AppRoute[] = [
+  // Common
+  {
+    path: '',
+    data: { expectedRole: UserRolesArray },
+    component: UserFormComponent,
+  },
+  {
+    path: 'edit',
+    component: UserFormComponent,
+    data: { expectedRole: UserRolesArray },
+  },
+  {
+    path: 'change-passwd',
+    component: UserFormComponent,
+    data: { expectedRole: UserRolesArray },
+  },
+  {
+    // Usuario administrador de hoteles
+    path: 'hotels',
+    data: { expectedRole: 'HOTEL_ADMIN' },
+    loadChildren: () =>
+      import('app/features/hotels').then((m) => m.MANAGERS_ROUTES),
+  },
+  {
+    // Usuario cliente
+    path: 'bookings',
+    data: { expectedRole: 'CLIENT' },
+    loadChildren: () =>
+      import('app/features/bookings').then((m) => m.CLIENT_BOOKINGS_ROUTES),
+  },
+];
diff --git a/angular/RestClient/src/app/page/unauthorized/unauthorized.component.ts b/angular/RestClient/src/app/page/unauthorized/unauthorized.component.ts
index 061a73dbe09d717285d19188179a450cd780a699..67f9df6fc352fa34000a0864d9cd71b11745fecd 100644
--- a/angular/RestClient/src/app/page/unauthorized/unauthorized.component.ts
+++ b/angular/RestClient/src/app/page/unauthorized/unauthorized.component.ts
@@ -1,6 +1,6 @@
 import { Component } from '@angular/core';
 import { RouterModule } from '@angular/router';
-import { SessionService } from '../../shared/session.service';
+import { SessionService } from '../../core/services/session/session.service';
 import { MatIconModule } from '@angular/material/icon';
 import { MatButtonModule } from '@angular/material/button';
 
diff --git a/angular/RestClient/src/app/security/rol.guard.ts b/angular/RestClient/src/app/security/rol.guard.ts
deleted file mode 100644
index 53017db2422c5f9e8c62c37622786bc4988673bf..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/app/security/rol.guard.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { inject } from '@angular/core';
-import { CanActivateFn, Router } from '@angular/router';
-import { SessionService } from '../shared/session.service';
-import { UserRol, Session } from '../types';
-import { map } from 'rxjs';
-
-export const rolGuard: CanActivateFn = (route, state) => {
-  const sessionService = inject(SessionService);
-  const router = inject(Router);
-  // Obtén el rol esperado desde los datos de la ruta
-  const expectedRole = route.data?.['expectedRole'];
-
-  // Verifica si el usuario tiene sesión activa
-  const session = sessionService.isValid();
-
-  if (!session) {
-    console.log('no session');
-    router.navigate(['/login']);
-    return false;
-  }
-
-  return sessionService.getSession().pipe(
-    map((session: Session | null) => {
-      if (!session) return false;
-
-      if (
-        Array.isArray(expectedRole) &&
-        (expectedRole as UserRol[]).includes(session.rol)
-      ) {
-        console.log('Rol in Rol arry');
-        return true;
-      } else if (session.rol === expectedRole) {
-        console.log('Rol valido');
-        return true;
-      }
-      console.log('Unautorizado');
-
-      // Redirige si el usuario no tiene el rol necesario
-      router.navigate(['/unauthorized']);
-      return false;
-    })
-  );
-};
diff --git a/angular/RestClient/src/app/shared/index.ts b/angular/RestClient/src/app/shared/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..025765515b7065a3a53b37ce41931562927ffa5d
--- /dev/null
+++ b/angular/RestClient/src/app/shared/index.ts
@@ -0,0 +1 @@
+export * from './navigation/navigation.component';
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.css b/angular/RestClient/src/app/shared/navigation/navigation.component.css
similarity index 100%
rename from angular/RestClient/src/app/core/navigation/navigation.component.css
rename to angular/RestClient/src/app/shared/navigation/navigation.component.css
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.html b/angular/RestClient/src/app/shared/navigation/navigation.component.html
similarity index 100%
rename from angular/RestClient/src/app/core/navigation/navigation.component.html
rename to angular/RestClient/src/app/shared/navigation/navigation.component.html
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.spec.ts b/angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts
similarity index 100%
rename from angular/RestClient/src/app/core/navigation/navigation.component.spec.ts
rename to angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.ts b/angular/RestClient/src/app/shared/navigation/navigation.component.ts
similarity index 90%
rename from angular/RestClient/src/app/core/navigation/navigation.component.ts
rename to angular/RestClient/src/app/shared/navigation/navigation.component.ts
index effeb032ae23e20086be4661a92971ac5543cb36..12f4164e9cffed5cbf23380f2c47d894fef82cea 100644
--- a/angular/RestClient/src/app/core/navigation/navigation.component.ts
+++ b/angular/RestClient/src/app/shared/navigation/navigation.component.ts
@@ -3,11 +3,8 @@ 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 { Session, User, UserRol } from '../../types';
-import { SessionService } from '../../shared/session.service';
-import { UserClientService } from '../../shared/user-client.service';
-import { AuthClientService } from '../../shared/auth-client.service';
-import { Observable } from 'rxjs';
+import { Session, UserRol } from '@core/models';
+import { SessionService } from '@core/services';
 
 var comp_id = 0;
 
diff --git a/angular/RestClient/src/app/types/index.ts b/angular/RestClient/src/app/types/index.ts
deleted file mode 100644
index 09338254dd1b87fdc9aa00cb7342f0865fc382de..0000000000000000000000000000000000000000
--- a/angular/RestClient/src/app/types/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { RoomType } from './Room';
-import { UserRol } from './User';
-
-export type * from './User';
-export type * from './Address';
-export type * from './Hotel';
-export type * from './Room';
-export const roomTypeArray: RoomType[] = ['SINGLE', 'DOUBLE', 'SUITE'];
-export type * from './Booking';
-export type * from './User';
-export const UserRolesArray: UserRol[] = ['CLIENT', 'HOTEL_ADMIN', 'ADMIN'];
-export type * from './Session';
diff --git a/angular/RestClient/src/app/utils/index.ts b/angular/RestClient/src/app/utils/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..04bca77e0dec46fccb655a9203c2c8ee57ba7ed2
--- /dev/null
+++ b/angular/RestClient/src/app/utils/index.ts
@@ -0,0 +1 @@
+export * from './utils';
diff --git a/angular/RestClient/src/environments/environment.development.ts b/angular/RestClient/src/environments/environment.development.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f274e5edf297c322280400000710ffbfd88f7711
--- /dev/null
+++ b/angular/RestClient/src/environments/environment.development.ts
@@ -0,0 +1 @@
+export const environment = {};
diff --git a/angular/RestClient/src/mocks/users.ts b/angular/RestClient/src/mocks/users.ts
index f6fafe67e13993f0e5b1a48c5443d43f6d3c2c3d..c21e6712745692d04764ac71105d66eed363c533 100644
--- a/angular/RestClient/src/mocks/users.ts
+++ b/angular/RestClient/src/mocks/users.ts
@@ -1,4 +1,4 @@
-import { Client, User } from '../app/types';
+import { Client, User } from '../app/core/models';
 
 export const users: Client[] = [
   {
diff --git a/angular/RestClient/suggested_struct.md b/angular/RestClient/suggested_struct.md
new file mode 100644
index 0000000000000000000000000000000000000000..e1d72cf57a09fa96ddc0983a895549d4dbc68028
--- /dev/null
+++ b/angular/RestClient/suggested_struct.md
@@ -0,0 +1,179 @@
+¡Gracias por compartir la estructura de tu proyecto! La organización que tienes ya está bastante bien y sigue un esquema modular lógico. Sin embargo, puedo ofrecerte algunas **sugerencias para mejorar la organización** y seguir las mejores prácticas modernas de Angular, especialmente para proyectos grandes como este.
+
+---
+
+### **Propuesta de Ajustes para Mejorar Escalabilidad y Mantenimiento**
+
+1. **Separa el código relacionado con "Core" y "Features" claramente**
+   Actualmente, dentro de `core` tienes una carpeta llamada `features`, lo cual puede generar confusión porque los módulos funcionales suelen estar en un nivel separado del núcleo.
+
+   **Propuesta:**
+   Mueve `features` al nivel raíz de `app/`. Así, `core` queda solo para configuraciones globales y servicios singleton, mientras que los módulos de funcionalidad se agrupan claramente en `features`.
+
+   ```
+   app/
+   ├── core/
+   │   ├── guards/
+   │   ├── interceptors/
+   │   ├── services/
+   │   ├── interfaces/ (puede fusionarse con `types` si prefieres)
+   │   └── core.module.ts
+   ├── features/ (antes dentro de core/features)
+   │   ├── auth/
+   │   ├── bookings/
+   │   ├── hotel/
+   │   ├── user/
+   │   └── ...
+   ```
+
+---
+
+2. **Reorganiza `shared` para dividir los servicios y componentes reutilizables**
+   Actualmente, `shared` contiene todos los servicios reutilizables. Esto está bien, pero puedes separar los servicios de otros posibles elementos reutilizables (como pipes, directivas, o componentes). Esto mejora la claridad y hace que sea más fácil expandir `shared` en el futuro.
+
+   **Propuesta:**
+   ```
+   shared/
+   ├── components/               # Componentes reutilizables (header, footer, spinner, etc.)
+   ├── directives/               # Directivas personalizadas (si las usas en el futuro)
+   ├── pipes/                    # Pipes personalizados
+   ├── services/                 # Servicios reutilizables (actualmente en `shared`)
+   │   ├── auth-client.service.ts
+   │   ├── booking-client.service.ts
+   │   ├── hotel-client.service.ts
+   │   ├── local-storage.service.ts
+   │   ├── session.service.ts
+   │   └── user-client.service.ts
+   └── shared.module.ts          # Opcional, exporta recursos reutilizables
+   ```
+
+---
+
+3. **Agrupa los tests de Guards, Interceptors y otros elementos de seguridad**
+   Los guards e interceptores relacionados con seguridad están correctamente en `security`. Sin embargo, para seguir un esquema uniforme, puedes agrupar sus tests (`*.spec.ts`) en subcarpetas junto con los archivos que prueban.
+
+   **Propuesta:**
+   ```
+   security/
+   ├── guards/
+   │   ├── rol.guard.ts
+   │   └── rol.guard.spec.ts
+   ├── interceptors/
+   │   ├── auth.interceptor.ts
+   │   └── auth.interceptor.spec.ts
+   ```
+
+---
+
+4. **Claridad en los módulos funcionales dentro de `features`**
+   Tus módulos funcionales (`auth`, `bookings`, `hotel`, `user`) están bien estructurados. Sin embargo, puedes incluir un archivo `routing` y agrupar los componentes y servicios que son específicos de cada módulo.
+
+   **Propuesta para un módulo funcional (ejemplo: `auth`)**:
+   ```
+   auth/
+   ├── components/
+   │   ├── login/
+   │   │   ├── login.component.ts
+   │   │   ├── login.component.html
+   │   │   └── login.component.css
+   │   ├── register/
+   │       ├── register.component.ts
+   │       ├── register.component.html
+   │       └── register.component.css
+   ├── auth-routing.module.ts   # Rutas específicas para el módulo
+   ├── auth.module.ts           # Módulo propio de Auth
+   └── services/
+       ├── auth.service.ts      # Servicios específicos del módulo
+       └── token.service.ts
+   ```
+
+   Esto hace que los servicios y componentes específicos de un módulo no se mezclen con los globales.
+
+---
+
+5. **Centraliza y organiza los tipos (o interfaces)**
+   Actualmente tienes una carpeta `types` con interfaces relacionadas con el dominio (`Address`, `Booking`, etc.). Esto está bien, pero puedes agruparlas en módulos de funcionalidades correspondientes si no son usadas globalmente.
+
+   **Propuesta:**
+   - Si **son compartidas por varios módulos**, mantenlas en `core/interfaces/`.
+   - Si **son específicas de un módulo**, muévelas al módulo correspondiente dentro de `features`.
+
+   **Ejemplo para `Booking.d.ts`:**
+   Si solo es usado por el módulo `bookings`, ubícalo así:
+   ```
+   features/bookings/interfaces/booking.interface.ts
+   ```
+
+   Y actualiza el import en cualquier lugar donde lo uses:
+   ```typescript
+   import { Booking } from '../features/bookings/interfaces/booking.interface';
+   ```
+
+---
+
+6. **Páginas específicas (como `unauthorized`)**
+   La carpeta `page/unauthorized` está correcta, pero en proyectos grandes suele ser más común incluir este tipo de páginas en un módulo funcional. Por ejemplo, si `unauthorized` está relacionado con autenticación, podría ir dentro de `features/auth`.
+
+   **Propuesta:**
+   ```
+   features/auth/
+   ├── unauthorized/
+   │   ├── unauthorized.component.ts
+   │   ├── unauthorized.component.html
+   │   └── unauthorized.component.css
+   ```
+
+   Si está pensada como una página global (accesible desde cualquier lugar), puedes dejarla en `core/` o en su propio módulo funcional como `pages/unauthorized`.
+
+---
+
+### **Versión Reorganizada**
+Tu estructura reorganizada podría verse así:
+```
+src/
+├── app/
+│   ├── core/
+│   │   ├── guards/
+│   │   │   ├── rol.guard.ts
+│   │   │   └── rol.guard.spec.ts
+│   │   ├── interceptors/
+│   │   │   ├── auth.interceptor.ts
+│   │   │   └── auth.interceptor.spec.ts
+│   │   ├── services/           # Servicios singleton
+│   │   ├── interfaces/         # Interfaces globales
+│   │   └── core.module.ts
+│   ├── shared/
+│   │   ├── components/
+│   │   │   ├── header/
+│   │   │   └── footer/
+│   │   ├── directives/
+│   │   ├── pipes/
+│   │   ├── services/
+│   │   └── shared.module.ts
+│   ├── features/
+│   │   ├── auth/
+│   │   │   ├── components/
+│   │   │   ├── services/
+│   │   │   ├── interfaces/
+│   │   │   ├── unauthorized/
+│   │   │   ├── auth-routing.module.ts
+│   │   │   └── auth.module.ts
+│   │   ├── bookings/
+│   │   ├── hotel/
+│   │   └── user/
+│   ├── app-routing.module.ts
+│   ├── app.component.ts
+│   └── app.module.ts
+├── environments/
+├── styles/
+└── utils/
+```
+
+---
+
+### **Beneficios de esta Reorganización**
+1. **Claridad:** Diferenciación clara entre módulos funcionales (`features`), servicios globales (`core`), y recursos reutilizables (`shared`).
+2. **Escalabilidad:** Módulos funcionales pueden crecer sin afectar otras partes del proyecto.
+3. **Mantenibilidad:** Cada archivo está en un lugar lógico, lo que facilita encontrar y modificar código.
+
+Si necesitas ejemplos de código para implementar alguna parte, ¡házmelo saber! 😊
diff --git a/angular/RestClient/suggested_tree b/angular/RestClient/suggested_tree
new file mode 100644
index 0000000000000000000000000000000000000000..25ac5d163023fcd24cfa22e63d69b8429b7c4b21
--- /dev/null
+++ b/angular/RestClient/suggested_tree
@@ -0,0 +1,38 @@
+src/
+├── app/
+│   ├── core/
+│   │   ├── guards/
+│   │   │   ├── rol.guard.ts
+│   │   │   └── rol.guard.spec.ts
+│   │   ├── interceptors/
+│   │   │   ├── auth.interceptor.ts
+│   │   │   └── auth.interceptor.spec.ts
+│   │   ├── services/           # Servicios singleton
+│   │   ├── interfaces/         # Interfaces globales
+│   │   └── core.module.ts
+│   ├── shared/
+│   │   ├── components/
+│   │   │   ├── header/
+│   │   │   └── footer/
+│   │   ├── directives/
+│   │   ├── pipes/
+│   │   ├── services/
+│   │   └── shared.module.ts
+│   ├── features/
+│   │   ├── auth/
+│   │   │   ├── components/
+│   │   │   ├── services/
+│   │   │   ├── interfaces/
+│   │   │   ├── unauthorized/
+│   │   │   ├── auth-routing.module.ts
+│   │   │   └── auth.module.ts
+│   │   ├── bookings/
+│   │   ├── hotel/
+│   │   └── user/
+│   ├── app-routing.module.ts
+│   ├── app.component.ts
+│   └── app.module.ts
+├── environments/
+├── styles/
+└── utils/
+
diff --git a/angular/RestClient/tsconfig.json b/angular/RestClient/tsconfig.json
index a8bb65b6e220b8a16a8cba8241833468f1145586..2f5f1c7db6874459db03595ba7a9f58e3e2f1a3d 100644
--- a/angular/RestClient/tsconfig.json
+++ b/angular/RestClient/tsconfig.json
@@ -19,10 +19,16 @@
     "importHelpers": true,
     "target": "ES2022",
     "module": "ES2022",
-    "lib": [
-      "ES2022",
-      "dom"
-    ]
+    "lib": ["ES2022", "dom"],
+    "baseUrl": "./src", // Define la base del proyecto
+    "paths": {
+      "@core/*": ["app/core/*"], // Alias para el core
+      "@shared": ["app/shared"], // Alias para shared
+      "@shared/*": ["app/shared/*"], // Alias para shared
+      "@features/*": ["app/core/features/*"], // Alias para features
+      "@utils/*": ["app/utils/*"], // Alias para utilidades
+      "@pages/*": ["app/pages/*"] // Alias para pages
+    }
   },
   "angularCompilerOptions": {
     "enableI18nLegacyMessageIdFormat": false,
diff --git a/java/roomBooking/.gitignore b/java/roomBooking/.gitignore
deleted file mode 100644
index 549e00a2a96fa9d7c5dbc9859664a78d980158c2..0000000000000000000000000000000000000000
--- a/java/roomBooking/.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/roomBooking/.mvn/wrapper/maven-wrapper.properties b/java/roomBooking/.mvn/wrapper/maven-wrapper.properties
deleted file mode 100644
index d58dfb70bab565a697e6854eb012d17e0fd39bd4..0000000000000000000000000000000000000000
--- a/java/roomBooking/.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/roomBooking/Dockerfile b/java/roomBooking/Dockerfile
deleted file mode 100644
index 8d0b79d6514534deddac782fc9367bcdbcaf89c3..0000000000000000000000000000000000000000
--- a/java/roomBooking/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/roomBooking/mvnw b/java/roomBooking/mvnw
deleted file mode 100755
index 19529ddf8c6eaa08c5c75ff80652d21ce4b72f8c..0000000000000000000000000000000000000000
--- a/java/roomBooking/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/roomBooking/mvnw.cmd b/java/roomBooking/mvnw.cmd
deleted file mode 100644
index 249bdf3822221aa612d1da2605316cabd7b07e50..0000000000000000000000000000000000000000
--- a/java/roomBooking/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/roomBooking/pom.xml b/java/roomBooking/pom.xml
deleted file mode 100644
index 30de244f0964028a4aa0b50df0ff2cf4f4b1102f..0000000000000000000000000000000000000000
--- a/java/roomBooking/pom.xml
+++ /dev/null
@@ -1,77 +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>roomBooking</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
-	<name>roomBooking</name>
-	<description>Room Booking 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>
-		<dependency>
-    <groupId>org.springframework.boot</groupId>
-    <artifactId>spring-boot-starter-security</artifactId>
-	</dependency>
-	<dependency>
-		<groupId>com.auth0</groupId>
-		<artifactId>java-jwt</artifactId>
-		<version>4.4.0</version>
-	</dependency>
-	<dependency>
-		<groupId>jakarta.servlet</groupId>
-		<artifactId>jakarta.servlet-api</artifactId>
-		<scope>provided</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/roomBooking/src/main/java/com/uva/monolith/RoomBookingApplication.java b/java/roomBooking/src/main/java/com/uva/monolith/RoomBookingApplication.java
deleted file mode 100644
index 0a5db248da6e6be909302e323931f79151b0ed62..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/RoomBookingApplication.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.monolith;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class RoomBookingApplication {
-
-	public static void main(String[] args) {
-		SpringApplication.run(RoomBookingApplication.class, args);
-	}
-
-}
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
deleted file mode 100644
index 8264f84a2e9f57dabaedc5892ea8a3ca0e931232..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/config/SecurityConfig.java
+++ /dev/null
@@ -1,49 +0,0 @@
-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.CLIENT.toString(), UserRol.HOTEL_ADMIN.toString(), UserRol.ADMIN.toString())
-                        // Acceso restringido a gestores de hoteles y administradores
-                        .requestMatchers(HttpMethod.GET, "hotels", "hotels/*").hasAnyRole(
-                                UserRol.CLIENT.toString(), UserRol.HOTEL_ADMIN.toString(), UserRol.ADMIN.toString())
-
-                        .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/roomBooking/src/main/java/com/uva/monolith/exceptions/GlobalExceptionHandler.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/GlobalExceptionHandler.java
deleted file mode 100644
index 9428c51a9c63c3623d44752c9e3cbe6cf78ac19f..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/exceptions/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.uva.monolith.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/monolith/exceptions/HotelNotFoundException.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/HotelNotFoundException.java
deleted file mode 100644
index 129a0b1086b4b78eb1f1725b9f241f51ce5540f8..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/exceptions/HotelNotFoundException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.monolith.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/monolith/exceptions/InvalidDateRangeException.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidDateRangeException.java
deleted file mode 100644
index 5fea986ef1e9279c459bc5aff10932049f283333..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidDateRangeException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.uva.monolith.exceptions;
-
-public class InvalidDateRangeException extends RuntimeException {
-    public InvalidDateRangeException(String message) {
-        super(message);
-    }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidRequestException.java b/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidRequestException.java
deleted file mode 100644
index ca09e054420dd174c4d2c3424dcc8fe74b6c8576..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/exceptions/InvalidRequestException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.monolith.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/roomBooking/src/main/java/com/uva/monolith/filter/JwtAuthenticationFilter.java b/java/roomBooking/src/main/java/com/uva/monolith/filter/JwtAuthenticationFilter.java
deleted file mode 100644
index 3b088ce78caee67736a2f1bc7f24f60e49b5a0fa..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/filter/JwtAuthenticationFilter.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package com.uva.monolith.filter;
-
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.JWTVerifier;
-import com.auth0.jwt.algorithms.Algorithm;
-import com.auth0.jwt.interfaces.DecodedJWT;
-import com.auth0.jwt.exceptions.JWTVerificationException;
-
-import org.springframework.beans.factory.annotation.Value;
-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.time.LocalDateTime;
-import java.util.Collections;
-
-@Component
-public class JwtAuthenticationFilter implements Filter {
-
-    @Value("${security.jwt.secret-key}")
-    private String secretKey;
-
-    @Value("${security.jwt.kid}")
-    private String kid;
-
-    @Value("${security.jwt.expiration-time}")
-    private long jwtExpiration;
-
-    private Algorithm getSigningAlgorithm() {
-        return Algorithm.HMAC256(secretKey); // Usar HMAC256 con la clave secreta
-    }
-
-    private String getTokenFromRequest(HttpServletRequest request) {
-        String authHeader = request.getHeader("Authorization");
-        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
-            return null;
-        }
-        return authHeader.substring(7);
-    }
-
-    private DecodedJWT validateAndDecodeToken(String token) {
-        try {
-            JWTVerifier verifier = JWT.require(getSigningAlgorithm()).build();
-            return verifier.verify(token); // Verifica y decodifica el token
-        } catch (JWTVerificationException ex) {
-            System.out.println(
-                    "[" + LocalDateTime.now().toString() + "] Error de verificación del token: " + ex.getMessage());
-            return null;
-        }
-    }
-
-    private String getEmailFromToken(DecodedJWT jwt) {
-        return jwt.getClaim("email").asString();
-    }
-
-    private UserRol getRoleFromToken(DecodedJWT jwt) {
-        String role = jwt.getClaim("rol").asString();
-        return UserRol.valueOf(role);
-    }
-
-    private String formatRole(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.print("[" + LocalDateTime.now().toString() + "] TOKEN: " + token);
-
-        if (token != null) {
-            DecodedJWT jwt = validateAndDecodeToken(token);
-            System.out.print(" " + jwt.toString() + " ");
-            if (jwt != null) {
-                String email = getEmailFromToken(jwt);
-                UserRol role = getRoleFromToken(jwt);
-                System.out.print(" email=" + email + " role=" + role + " ");
-
-                if (email != null && role != null && SecurityContextHolder.getContext().getAuthentication() == null) {
-                    // Crear la autoridad con el rol del token
-                    SimpleGrantedAuthority authority = new SimpleGrantedAuthority(formatRole(role));
-
-                    // Crear autenticación
-                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(email,
-                            null, Collections.singletonList(authority));
-                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
-
-                    // Establecer autenticación en el contexto de seguridad
-                    SecurityContextHolder.getContext().setAuthentication(authentication);
-                }
-            }
-        }
-
-        // Continuar con el resto de filtros
-        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
deleted file mode 100644
index 61feb5104e87b7fcd333e36f07493532f397dbcf..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/controllers/BookingController.java
+++ /dev/null
@@ -1,62 +0,0 @@
-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);
-        }
-    }
-
-    @DeleteMapping("/hotel/{hotelId}")
-    public ResponseEntity<Void> deleteBookingsByHotelId(@PathVariable Integer hotelId) {
-        try {
-            bookingService.deleteBookingsByHotelId(hotelId);
-            return new ResponseEntity<>(HttpStatus.ACCEPTED);
-        } catch (RuntimeException e) {
-            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
-        }
-    }
-
-}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/models/Booking.java b/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/models/Booking.java
deleted file mode 100644
index 533ee0c7a1fa053dce449b855f1e46e08dabbe66..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/models/Booking.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package com.uva.monolith.services.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;
-
-import com.uva.monolith.services.hotels.models.Room;
-import com.uva.monolith.services.users.models.Client;
-
-@Entity
-@Table(name = "bookings")
-public class Booking {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Basic(optional = false)
-    private int id;
-    @JoinColumn(name = "user_id", referencedColumnName = "id")
-    @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
-    private Client userId;
-    @JoinColumn(name = "room_id", referencedColumnName = "id")
-    @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
-    private Room 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, Client userId, Room 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(Client userId) {
-        this.userId = userId;
-    }
-
-    public Client getUserId() {
-        return this.userId;
-    }
-
-    public void setRoomId(Room roomID) {
-        this.roomId = roomID;
-    }
-
-    public Room 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/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
deleted file mode 100644
index b5ace65939b898798e6e5416fedda793388f2615..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/repositories/BookingRepository.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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
deleted file mode 100644
index 36c51e602fe7cf9bfe9b88f5261104a3c068c782..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/bookings/services/BookingService.java
+++ /dev/null
@@ -1,93 +0,0 @@
-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);
-    }
-
-    public void deleteBookingsByHotelId(int hotelId) {
-        bookingRepository.deleteAllByHotelId(hotelId);
-    }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
deleted file mode 100644
index 781cb6278b0b40d237b603d7cfc61a63b7b2af0f..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.uva.monolith.services.hotels.controllers;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.time.LocalDate;
-
-import org.springframework.beans.factory.annotation.Autowired;
-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;
-import com.uva.monolith.services.users.models.HotelManager;
-import com.uva.monolith.services.users.repositories.HotelManagerRepository;
-
-@RestController
-@RequestMapping("hotels")
-@CrossOrigin(origins = "*")
-public class HotelController {
-    @Autowired
-    private HotelManagerRepository hotelManagerRepository;
-    private final HotelRepository hotelRepository;
-    private final RoomRepository roomRepository;
-    private final BookingRepository bookingRepository;
-
-    public HotelController(HotelRepository hotelRepository, RoomRepository roomRepository,
-            BookingRepository bookingRepository) {
-        this.hotelRepository = hotelRepository;
-        this.roomRepository = roomRepository;
-        this.bookingRepository = bookingRepository;
-    }
-
-    // Obtener todos los hoteles
-    @GetMapping
-    public List<Hotel> getAllHotels(
-            @RequestParam(required = false) Integer managerId,
-            @RequestParam(required = false) LocalDate start,
-            @RequestParam(required = false) LocalDate end) {
-        List<Hotel> hotels = (managerId != null)
-                ? hotelRepository.findAllByHotelManager(managerId)
-                : hotelRepository.findAll();
-        if (start != null && end != null) {
-            // Filtramos para los hoteles que
-            // tengan habitaciones disponibles para ese rango de fechas
-            System.out.println(start);
-            System.out.println(end);
-            hotels = hotels.stream().map(h -> {
-                if (h.getRooms().size() == 0)
-                    return h;
-                h.setRooms(roomRepository.findAvailableRoomsByHotelAndDates(h.getId(), start, end));
-                return h;
-            }).filter(h -> h.getRooms().size() >= 0).toList();
-        }
-        return hotels;
-    }
-
-    // Añadir un hotel con sus habitaciones
-    @PostMapping
-    public ResponseEntity<Hotel> addHotel(@RequestBody Hotel hotel) {
-        Optional<HotelManager> hm = hotelManagerRepository.findById(hotel.getHotelManager().getId());
-        if (!hm.isPresent()) {
-            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
-        }
-        hotel.setHotelManager(hm.get());
-        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);
-        HotelManager hm = target.getHotelManager();
-        hm.getHotels().removeIf(h -> h.getId() == target.getId());
-        hotelManagerRepository.save(hm);
-        bookingRepository.flush();
-        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;
-        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 = roomRepository.findAvailableRoomsByHotelAndDates(hotelId, start, end);
-        } else {
-            rooms = roomRepository.findAllByHotelId(hotelId);
-        }
-        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/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Address.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Address.java
deleted file mode 100644
index 5f31a2a530da46c00460ad6cc6151b0769c1da61..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Address.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package com.uva.monolith.services.hotels.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/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java
deleted file mode 100644
index 21f5cec8b44f9fae1a566b7af92964d30b654546..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Hotel.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.uva.monolith.services.hotels.models;
-
-import java.util.List;
-
-import com.uva.monolith.services.users.models.HotelManager;
-
-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.ManyToOne;
-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;
-
-  @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, HotelManager hotelManager) {
-    setId(id);
-    setName(name);
-    setAddress(address);
-    setRooms(rooms);
-    setHotelManager(hotelManager);
-  }
-
-  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));
-  }
-
-  public void setHotelManager(HotelManager hotelManager) {
-    this.hotelManager = hotelManager;
-  }
-
-  public HotelManager getHotelManager() {
-    return hotelManager;
-  }
-}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Room.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Room.java
deleted file mode 100644
index 72a6a728f729dc7b93b727606172de7cbe385ebb..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/Room.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.uva.monolith.services.hotels.models;
-
-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.FetchType;
-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.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 RoomType type;
-    @Column(name = "available", nullable = false)
-    private boolean available;
-    @JsonIgnore
-    @OneToMany(mappedBy = "roomId", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
-    private List<Booking> bookings;
-
-    public Room() {
-    }
-
-    public Room(int id, Hotel hotelId, String roomNumber, RoomType type, boolean available, List<Booking> bookings) {
-        this.id = id;
-        this.hotel = hotelId;
-        this.roomNumber = roomNumber;
-        this.type = type;
-        this.available = available;
-        this.bookings = bookings;
-    }
-
-    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(RoomType type) {
-        this.type = type;
-    }
-
-    public RoomType getType() {
-        return this.type;
-    }
-
-    public void setAvailable(boolean available) {
-        this.available = available;
-    }
-
-    public boolean isAvailable() {
-        return this.available;
-    }
-
-    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/hotels/models/RoomType.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/RoomType.java
deleted file mode 100644
index b9e82584850795afa7c7392248e3a6472ce24ac0..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/models/RoomType.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.uva.monolith.services.hotels.models;
-
-public enum RoomType {
-    SINGLE,
-    DOUBLE,
-    SUITE
-}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/HotelRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/HotelRepository.java
deleted file mode 100644
index eddb6640a275284cb70bde60a29afd33039ba454..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/HotelRepository.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.uva.monolith.services.hotels.repositories;
-
-import java.util.List;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Query;
-
-import com.uva.monolith.services.hotels.models.Hotel;
-
-public interface HotelRepository extends JpaRepository<Hotel, Integer> {
-    @Query("SELECT h FROM Hotel h WHERE h.hotelManager.id = ?1")
-    List<Hotel> findAllByHotelManager(Integer hotelManager);
-}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/RoomRepository.java b/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/RoomRepository.java
deleted file mode 100644
index 15cc3d370129e0753b9ac9b1eb24136c93bf5405..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/hotels/repositories/RoomRepository.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.uva.monolith.services.hotels.repositories;
-
-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;
-
-public interface RoomRepository extends JpaRepository<Room, Integer> {
-
-    Optional<Room> findByIdAndHotelId(int id, int hotelId);
-
-    // Encontrar todas las habitaciones de un hotel
-    List<Room> findAllByHotelId(int hotelId);
-
-    // Encontrar habitaciones disponibles de un hotel en un rango de fechas
-    @Query("""
-                SELECT r FROM Room r
-                WHERE r.hotel.id = ?1
-                AND r.available = true
-                AND NOT EXISTS (
-                    SELECT b FROM Booking b
-                    WHERE b.roomId.id = r.id
-                    AND (
-                        b.endDate >= ?2
-                        OR
-                        ?3 >= b.startDate
-                    )
-                )
-            """)
-    List<Room> findAvailableRoomsByHotelAndDates(
-            int hotelId, LocalDate startDate, LocalDate endDate);
-}
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
deleted file mode 100644
index 15fc498b79e239020aba6833ae9dbfaa8eeb59ee..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/controllers/UserController.java
+++ /dev/null
@@ -1,112 +0,0 @@
-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.registerNewUser(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) {
-    System.err.println(json.entrySet().size());
-    json.keySet().forEach(k -> System.err.println(k));
-    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
deleted file mode 100644
index 8f334813beee8cb95caa275c66e46c9c539f2bd5..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/AuthResponse.java
+++ /dev/null
@@ -1,51 +0,0 @@
-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
deleted file mode 100644
index e106ecd3789a0237602e3194feacab7ddcbf4dfd..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/Client.java
+++ /dev/null
@@ -1,65 +0,0 @@
-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
deleted file mode 100644
index 0e6f4b0aafa35ab8b23d202814c1fabefdcf86ed..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/HotelManager.java
+++ /dev/null
@@ -1,38 +0,0 @@
-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/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java
deleted file mode 100644
index ecfd33d1e39f6760f39fb0ad48fa195cd71432ea..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/User.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.uva.monolith.services.users.models;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
-import jakarta.persistence.Basic;
-import jakarta.persistence.Column;
-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.Inheritance;
-import jakarta.persistence.InheritanceType;
-import jakarta.persistence.Table;
-
-@Entity
-@Inheritance(strategy = InheritanceType.JOINED)
-@Table(name = "users")
-public class User {
-
-  @Id
-  @GeneratedValue(strategy = GenerationType.IDENTITY)
-  @Basic(optional = false)
-  @Column(nullable = false)
-  private int id;
-
-  @Basic(optional = false)
-  @Column(nullable = false)
-  private String name;
-
-  @Basic(optional = false)
-  @Column(nullable = false, unique = true)
-  private String email;
-
-  @Basic(optional = false)
-  @Column(nullable = false)
-  private String password;
-
-  @Basic(optional = false)
-  @Column(nullable = false)
-  @Enumerated(EnumType.STRING)
-  private UserRol rol = UserRol.CLIENT;
-
-  public User() {
-  }
-
-  public User(int id, String name, String email, String password, UserRol rol) {
-    setId(id);
-    setName(name);
-    setEmail(email);
-    setRol(rol);
-  }
-
-  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 String getPassword() {
-    return password;
-  }
-
-  public void setPassword(String rawPassword) {
-    this.password = rawPassword;
-  }
-
-  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/UserRol.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java
deleted file mode 100644
index f408ba5ef9d34d96c32d3c42a6c2c51b1c6f22b1..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserRol.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.uva.monolith.services.users.models;
-
-public enum UserRol {
-  ADMIN, HOTEL_ADMIN, CLIENT
-}
diff --git a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserStatus.java b/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserStatus.java
deleted file mode 100644
index 362b8688260d4c13dc4a8eae205411c9d5533d79..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/models/UserStatus.java
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 1c1b46fbe665075b8f817367ff14ee65cf69ff76..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/ClientRepository.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index 092a251b199fdecd80a2654fc3e6c96d1b7eb7f4..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/HotelManagerRepository.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index e5b44c976f095719854aa8070abc843b898036fe..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/repositories/UserRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index bdd5b9db80a7c699844cfcd48669171ffbe6b8f0..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/java/com/uva/monolith/services/users/services/UserService.java
+++ /dev/null
@@ -1,132 +0,0 @@
-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.HotelManager;
-import com.uva.monolith.services.users.models.User;
-import com.uva.monolith.services.users.models.UserRol;
-import com.uva.monolith.services.users.models.UserStatus;
-import com.uva.monolith.services.users.repositories.ClientRepository;
-import com.uva.monolith.services.users.repositories.HotelManagerRepository;
-import com.uva.monolith.services.users.repositories.UserRepository;
-
-@Service
-public class UserService {
-
-  @Autowired
-  private UserRepository userRepository;
-
-  @Autowired
-  private ClientRepository clientRepository;
-
-  @Autowired
-  private HotelManagerRepository hotelManagerRepository;
-
-  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);
-    return auth;
-  }
-
-  public User registerNewUser(User registerRequest) {
-    User newUser;
-
-    // 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:
-        User admin = new User();
-        BeanUtils.copyProperties(registerRequest, admin);
-        newUser = admin; // userAPI.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;
-  }
-
-  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/resources/application.properties b/java/roomBooking/src/main/resources/application.properties
deleted file mode 100644
index e9b75a35a39f7947153b79b234d6377a853078d4..0000000000000000000000000000000000000000
--- a/java/roomBooking/src/main/resources/application.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-spring.application.name=roomBooking
-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
-spring.security.user.name=admin
-spring.security.user.password=admin
-
-# 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
-external.services.auth.host=localhost:8101
-
-security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
-# 1h in millisecond
-security.jwt.expiration-time=3600000
-security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
\ No newline at end of file
diff --git a/java/roomBooking/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/roomBooking/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java
deleted file mode 100644
index 3b50599492c36017391c0dcabd81573f123a809a..0000000000000000000000000000000000000000
--- a/java/roomBooking/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/auth/src/main/java/com/uva/authentication/api/UserAPI.java b/java/services/auth/src/main/java/com/uva/authentication/api/UserAPI.java
index d61a328f4353b10ee58bec766bb2ba24b047cd82..6239c85caa1aeca7f4fa838df9a940e11d0907a0 100644
--- 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
@@ -53,7 +53,7 @@ public class UserAPI {
    */
   public User registerUser(RegisterRequest registerRequest) {
     String url = USER_API_URL;
-    System.out.println(registerRequest + " " + registerRequest.getPassword());
+    System.out.println(url + " " + registerRequest);
     ResponseEntity<User> userResponse = restTemplate.postForEntity(url, registerRequest, User.class);
     if (!userResponse.getStatusCode().is2xxSuccessful()) {
       String errorMessage = "Failed to register user: " + userResponse.getStatusCode() + ". " + userResponse.getBody();
@@ -80,4 +80,10 @@ public class UserAPI {
     restTemplate.put(url, body, id);
   }
 
+  public void deleteUser(User user) {
+    String url = USER_API_URL + "/{id}";
+
+    restTemplate.delete(url, user.getId());
+  }
+
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java
index 9ab4fa43b1587585cfdf4c1cd6d80b9556a78606..dbcefe7ec34f65cca38b60db09be7355a98b73a7 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateConfig.java
@@ -7,19 +7,16 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.client.RestTemplate;
 
-import com.uva.authentication.interceptor.AuthHttpInterceptor;
-
 @Configuration
 public class RestTemplateConfig {
 
     @Autowired
-    private AuthHttpInterceptor jwtInterceptor;
+    private RestTemplateInterceptor interceptor;
 
     @Bean
     RestTemplate restTemplate() {
         RestTemplate restTemplate = new RestTemplate();
-        restTemplate.setInterceptors(List.of(jwtInterceptor));
-
+        restTemplate.setInterceptors(List.of(interceptor));
         return restTemplate;
 
     }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateInterceptor.java b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..25b59946b262e6e8026f5f05ebd098e7dc9674be
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/config/RestTemplateInterceptor.java
@@ -0,0 +1,33 @@
+package com.uva.authentication.config;
+
+import org.springframework.http.HttpRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.stereotype.Component;
+
+import com.uva.authentication.utils.JwtUtil;
+
+import java.io.IOException;
+
+@Component
+public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
+
+  @Autowired
+  private JwtUtil jwtUtil;
+
+  @Override
+  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
+      throws IOException {
+
+    // Añadir el encabezado "Authorization" con el valor "Bearer <token>"
+    HttpHeaders headers = request.getHeaders();
+    headers.add("Authorization",
+        "Bearer " + jwtUtil.getOwnInternalToken());
+
+    // Continuar con la solicitud
+    return execution.execute(request, body);
+  }
+}
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
index 83041cc56f5019ea047e41c56dae8224828f792a..7dfa56acc48bad46f862f259c15f90b8e172ad01 100644
--- 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
@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
 @RestController
+@RequestMapping("auth")
 @CrossOrigin(origins = "*")
 public class AuthController {
 
@@ -23,55 +24,52 @@ public class AuthController {
     @PostMapping("/login")
     public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
         try {
-            String token = authService.login(loginRequest);
-            return ResponseEntity.ok(new JwtAuthResponse(token));
+            return authService.login(loginRequest);
         } catch (HttpClientErrorException e) {
             if (e.getStatusCode() == HttpStatus.FORBIDDEN) {
-                return new ResponseEntity<String>(e.getMessage(), HttpStatus.FORBIDDEN);
+                return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);
             }
         }
-        return new ResponseEntity<String>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+        return new ResponseEntity<>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
     }
 
     @PostMapping("/register")
     public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest) {
         try {
-            String token = authService.register(registerRequest);
-            return ResponseEntity.ok(new JwtAuthResponse(token));
+            return authService.register(registerRequest);
         } catch (HttpClientErrorException e) {
-            if (e.getStatusCode() == HttpStatus.CONFLICT) {
-                return new ResponseEntity<String>(e.getMessage(), HttpStatus.CONFLICT);
-            }
-            e.printStackTrace(System.err);
+            if (e.getStatusCode() == HttpStatus.CONFLICT)
+                return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT);
         }
 
-        return new ResponseEntity<String>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
+        return new ResponseEntity<>("Algo no fue bien", HttpStatus.UNAUTHORIZED);
     }
 
-    private boolean validStrings(String... args) {
-        for (String arg : args) {
-            if (arg == null || arg.isBlank())
-                return false;
-        }
-        return true;
+    @PostMapping("/password")
+    public ResponseEntity<?> changePassword(@RequestBody Map<String, String> json,
+            @RequestHeader(value = "Authorization", required = false) String authorization) {
+        if (authorization == null || !authorization.startsWith("Bearer "))
+            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+
+        String token = authorization.substring(7);
+
+        String actualPassword = json.get("password");
+        String newPassword = json.get("newPassword");
+
+        return authService.changePassword(token, actualPassword, newPassword);
     }
 
-    @PostMapping("/password")
-    public ResponseEntity<?> postMethodName(@RequestBody Map<String, String> json) {
-        // TODO adaptar a comportamiento de admin
-        String email = json.get("email");
-        String actualPassword = json.get("actual");
-        String newPassword = json.get("new");
+    @PostMapping("/delete/{id}")
+    public Object postMethodName(@PathVariable int id, @RequestBody Map<String, String> json,
+            @RequestHeader(value = "Authorization", required = false) String authorization) {
+        if (authorization == null || !authorization.startsWith("Bearer "))
+            return new ResponseEntity<>(HttpStatus.FORBIDDEN);
 
-        if (!validStrings(email, actualPassword, newPassword))
-            return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
+        String token = authorization.substring(7);
 
-        try {
-            // TODO extraer información del token?
-            String token = authService.changePassword(email, actualPassword, newPassword);
-            return ResponseEntity.ok(new JwtAuthResponse(token));
-        } catch (Exception e) {
-            return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
-        }
+        String actualPassword = json.get("password");
+
+        return authService.deleteUser(token, id, actualPassword);
     }
+
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/controllers/TokenController.java b/java/services/auth/src/main/java/com/uva/authentication/controllers/TokenController.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e33376dd18629f48bd6863bd8beb06465455901
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/controllers/TokenController.java
@@ -0,0 +1,47 @@
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.uva.authentication.models.JwtAuth;
+import com.uva.authentication.services.TokenService;
+
+@RestController
+@RequestMapping("/token")
+public class TokenController {
+
+  @Autowired
+  private TokenService tokenService;
+
+  @PostMapping("/validate")
+  public ResponseEntity<?> validateToken(@RequestBody JwtAuth tokenRequest) {
+    boolean isValid = tokenService.validateToken(tokenRequest.getToken());
+    if (isValid) {
+      return ResponseEntity.ok("Token is valid");
+    } else {
+      return new ResponseEntity<>("Token not valid or expired", HttpStatus.UNAUTHORIZED);
+    }
+  }
+
+  @PostMapping("/info")
+  public ResponseEntity<?> getTokenInfo(@RequestBody JwtAuth tokenRequest) {
+    return tokenService.getTokenInf(tokenRequest.getToken());
+  }
+
+  @PostMapping("/service")
+  public ResponseEntity<?> identifyService(@RequestBody JsonNode request) {
+    JsonNode name = request.get("service");
+
+    if (name == null)
+      return new ResponseEntity<>("Missing required fields", HttpStatus.BAD_REQUEST);
+
+    return tokenService.identifyService(name.asText());
+  }
+
+}
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 6d4b8d58dbb5560de50b5b2149cbe3f181687446..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/exceptions/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,51 +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 c642139b421a5cf864218fa2d0063f955335c5b7..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 c3dc917fb03495480007365b117e185521cf7bf2..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/exceptions/InvalidDateRangeException.java
+++ /dev/null
@@ -1,7 +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 499a320e58ecd7576cbfff39101db14395f0edbe..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/interceptor/AuthHttpInterceptor.java b/java/services/auth/src/main/java/com/uva/authentication/interceptor/AuthHttpInterceptor.java
deleted file mode 100644
index b64a0f69a673dcac07e93616c3affad5f6be3be5..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/interceptor/AuthHttpInterceptor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.uva.authentication.interceptor;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpRequest;
-import org.springframework.http.client.ClientHttpRequestExecution;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.http.client.ClientHttpRequestInterceptor;
-import org.springframework.stereotype.Component;
-
-import com.uva.authentication.models.remote.User;
-import com.uva.authentication.models.remote.UserRol;
-import com.uva.authentication.utils.JwtUtil;
-
-import java.io.IOException;
-
-@Component
-public class AuthHttpInterceptor implements ClientHttpRequestInterceptor {
-
-  @Autowired
-  private JwtUtil jwtUtil;
-
-  private String token;
-  private final User USER = new User(-1, "auth", "auth@dev.com", null, UserRol.ADMIN);
-
-  private String getAccessToken() {
-    if (token == null || token.isEmpty()) {
-      // TODO cambiar también si el token ha caducado
-      token = jwtUtil.generateToken(USER);
-    }
-    return token;
-
-  }
-
-  @Override
-  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
-      throws IOException {
-    // Generar o cargar el JWT token desde el bean JwtUtil
-    String jwtToken = getAccessToken();
-
-    // System.out.println("Using token " + jwtToken);
-
-    // Agregar el token al encabezado Authorization
-    request.getHeaders().add("Authorization", "Bearer " + jwtToken);
-
-    // Continuar con la ejecución de la solicitud
-    return execution.execute(request, body);
-  }
-}
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/JwtAuth.java
similarity index 51%
rename from java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java
rename to java/services/auth/src/main/java/com/uva/authentication/models/JwtAuth.java
index 148730189d6c5a29df507bc3cd10eef7a9b274e6..1736439a1b93980155336707350f695a9f56c0ed 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/models/AuthResponse.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuth.java
@@ -1,20 +1,16 @@
 package com.uva.authentication.models;
 
-import com.uva.authentication.models.remote.UserRol;
-
 import lombok.AllArgsConstructor;
+import lombok.Data;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 
-@AllArgsConstructor
-@NoArgsConstructor
-@Setter
 @Getter
-public class AuthResponse {
-  private int id;
-  private String name;
-  private String email;
-  private String password;
-  private UserRol rol;
+@Setter
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class JwtAuth {
+  private String token;
 }
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
deleted file mode 100644
index a9566954c35ce71864881e320843e270a998b9da..0000000000000000000000000000000000000000
--- a/java/services/auth/src/main/java/com/uva/authentication/models/JwtAuthResponse.java
+++ /dev/null
@@ -1,14 +0,0 @@
-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/TokenData.java b/java/services/auth/src/main/java/com/uva/authentication/models/TokenData.java
new file mode 100644
index 0000000000000000000000000000000000000000..d503f9193f58a44dee2a0b184ee654af4893999f
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/TokenData.java
@@ -0,0 +1,55 @@
+package com.uva.authentication.models;
+
+import java.lang.reflect.Field;
+
+import com.auth0.jwt.interfaces.Claim;
+import com.auth0.jwt.interfaces.DecodedJWT;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Data
+public class TokenData {
+  private Integer id;
+  private String name;
+  private String email;
+  private String rol;
+  private String service;
+
+  private String subject;
+  private String audience;
+  private Long ttl;
+
+  public TokenData(DecodedJWT decoded, long ttl) {
+
+    subject = decoded.getSubject();
+    audience = decoded.getAudience().get(0);
+    this.ttl = ttl;
+
+    for (Field field : this.getClass().getDeclaredFields()) {
+      field.setAccessible(true);
+
+      // Verificamos si el campo está en el mapa y asignamos el valor
+      Claim claim = decoded.getClaim(field.getName());
+      if (!claim.isMissing()) {
+        try {
+          // Dependiendo del tipo de campo, asignamos el valor
+          if (field.getType() == Integer.class) {
+            field.set(this, Integer.parseInt(claim.asString()));
+          } else if (field.getType() == String.class) {
+            field.set(this, claim.asString());
+          }
+        } catch (IllegalAccessException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+  }
+
+  public boolean isAdmin() {
+    return rol != null && rol == "ADMIN";
+  }
+}
\ No newline at end of file
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/TokenRequest.java b/java/services/auth/src/main/java/com/uva/authentication/models/TokenRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e63522e1a8660e71573fdb018aaae5f5596517ce
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/TokenRequest.java
@@ -0,0 +1,16 @@
+package com.uva.authentication.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TokenRequest {
+  private String token;
+}
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
index ae8de366340950b1bb5af476600408446a2d3f32..10049fc82e340fab5885cbd523f0962fc03292f5 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
@@ -16,6 +16,7 @@ public class User extends RegisterRequest {
 
   public User(int id, String email, String password, String name, UserRol rol) {
     super();
+    this.id = id;
     setEmail(email);
     setName(name);
     setPassword(password);
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
index 2cb39bb4f6174faf20c7174269c835f7c6b80cc2..fe4d90dd1dd595f4c09ec699b452910352b406d5 100644
--- 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
@@ -1,5 +1,5 @@
 package com.uva.authentication.models.remote;
 
 public enum UserRol {
-  ADMIN, AUTH, HOTEL_ADMIN, CLIENT
+  ADMIN, HOTEL_ADMIN, CLIENT
 }
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
index 67cf0b7308c3979274697da16bc0f0f103227aa9..03f2b6c132f4bf9531f891d34471d6484197a9dd 100644
--- 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
@@ -3,12 +3,16 @@ package com.uva.authentication.services;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.servlet.function.EntityResponse;
 
 import com.uva.authentication.api.UserAPI;
+import com.uva.authentication.models.JwtAuth;
 import com.uva.authentication.models.LoginRequest;
 import com.uva.authentication.models.RegisterRequest;
+import com.uva.authentication.models.TokenData;
 import com.uva.authentication.models.remote.User;
 import com.uva.authentication.utils.JwtUtil;
 import com.uva.authentication.utils.SecurityUtils;
@@ -35,17 +39,17 @@ public class AuthService {
    * @return token for identify the user
    * @throws HttpClientErrorException(FORBIDDEN) if the credentials are invalid
    */
-  public String login(LoginRequest loginRequest) {
+  public ResponseEntity<?> login(LoginRequest loginRequest) {
     User user = userAPI.getUserByEmail(loginRequest.getEmail());
 
-    if (!authenticateUser(loginRequest, user)) {
+    if (!authenticateUser(loginRequest, user))
       throw new HttpClientErrorException(HttpStatus.FORBIDDEN, "Invalid credentials");
-    }
 
-    return jwtUtil.generateToken(user);
+    String token = jwtUtil.generateToken(user);
+    return ResponseEntity.ok(new JwtAuth(token));
   }
 
-  public String register(RegisterRequest registerRequest) {
+  public ResponseEntity<?> register(RegisterRequest registerRequest) {
     String plainTextPassword = registerRequest.getPassword();
     // Ciframos la contraseña
     String hashPass = SecurityUtils.encrypt(plainTextPassword);
@@ -56,21 +60,66 @@ public class AuthService {
     BeanUtils.copyProperties(user, logReq);
     // Recuperamos la contraseña y lo loggeamos
     logReq.setPassword(plainTextPassword);
-    System.err.println(logReq);
     return login(logReq);
   }
 
-  public String changePassword(String email, String actualPass, String newPass) {
+  private boolean validStrings(String... args) {
+    for (String arg : args) {
+      if (arg == null || arg.isBlank())
+        return false;
+    }
+    return true;
+  }
+
+  private User getUser(String email, String password) {
     User user = userAPI.getUserByEmail(email);
-    // Validamos la anterior contraseña
-    if (SecurityUtils.checkPassword(actualPass, user.getPassword())) {
+    boolean correctPassword = SecurityUtils.checkPassword(password, user.getPassword());
+    return correctPassword ? user : null;
+  }
+
+  public ResponseEntity<?> changePassword(String token, String actualPass, String newPass) {
+    TokenData decoded = jwtUtil.decodeToken(token);
+    if (decoded == null)
+      return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+
+    String email = decoded.getEmail();
+    User user = getUser(email, actualPass);
+
+    boolean changePasswordAllowed = decoded.isAdmin() || user != null;
+
+    if (user != null && !validStrings(actualPass, newPass))
+      return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+
+    if (changePasswordAllowed) {
       // Actualizamos la nueva
       String hashPass = SecurityUtils.encrypt(newPass);
       userAPI.changePassword(user, hashPass);
       // Hacemos un login con los nuevos datos
       return login(new LoginRequest(email, newPass));
     } else {
-      throw new HttpClientErrorException(HttpStatus.FORBIDDEN, "Invalid credentials");
+      return new ResponseEntity<>("Invalid credentials", HttpStatus.FORBIDDEN);
+    }
+  }
+
+  public ResponseEntity<?> deleteUser(String token, int id, String password) {
+    TokenData decoded = jwtUtil.decodeToken(token);
+    if (decoded == null)
+      return new ResponseEntity<>(HttpStatus.FORBIDDEN);
+
+    String email = decoded.getEmail();
+    User user = getUser(email, password);
+
+    boolean changePasswordAllowed = decoded.isAdmin()
+        || (user != null && user.getId() == id);
+
+    if (user != null && !validStrings(password))
+      return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+
+    if (changePasswordAllowed) {
+      userAPI.deleteUser(user);
+      return new ResponseEntity<>(HttpStatus.ACCEPTED);
+    } else {
+      return new ResponseEntity<>("Invalid credentials", HttpStatus.FORBIDDEN);
     }
   }
 }
diff --git a/java/services/auth/src/main/java/com/uva/authentication/services/TokenService.java b/java/services/auth/src/main/java/com/uva/authentication/services/TokenService.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2a00805f914c4aa95e29e244ece3826db25796c
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/services/TokenService.java
@@ -0,0 +1,35 @@
+package com.uva.authentication.services;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import com.uva.authentication.models.JwtAuth;
+import com.uva.authentication.models.TokenData;
+import com.uva.authentication.utils.JwtUtil;
+
+@Service
+public class TokenService {
+
+  @Autowired
+  private JwtUtil jwtUtil;
+
+  public boolean validateToken(String token) {
+    return jwtUtil.validate(token) != null;
+  }
+
+  public ResponseEntity<?> identifyService(String name) {
+    if (name == null)
+      return new ResponseEntity<>("Token has expire or is malformed", HttpStatus.FORBIDDEN);
+    String token = jwtUtil.generateInternalToken(name);
+    return ResponseEntity.ok(new JwtAuth(token));
+  }
+
+  public ResponseEntity<?> getTokenInf(String token) {
+    TokenData decoded = jwtUtil.decodeToken(token);
+    if (decoded == null)
+      return new ResponseEntity<>("Token has expire or is malformed", HttpStatus.FORBIDDEN);
+    return ResponseEntity.ok(decoded);
+  }
+}
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
index 7b5bbf50066d94d8de2fced81890d5ce8ea93569..d633043cce2da7d19a75b7bf32db38bd52905e5f 100644
--- 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
@@ -1,44 +1,117 @@
 package com.uva.authentication.utils;
 
 import java.util.Date;
-
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpClientErrorException;
 
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.algorithms.Algorithm;
+import com.uva.authentication.models.TokenData;
 import com.uva.authentication.models.remote.User;
 
+import com.auth0.jwt.interfaces.DecodedJWT;
+
+import java.time.Instant;
+
 @Component
 public class JwtUtil {
 
+  @Value("${security.jwt.kid}")
+  private String kid;
+
   @Value("${security.jwt.secret-key}")
   private String secretKey;
 
-  @Value("${security.jwt.kid}")
-  private String kid;
+  @Value("${security.jwt.internal.expiration}")
+  private long intJwtExpiration;
+
+  @Value("${security.jwt.external.expiration}")
+  private long extJwtExpiration;
+
+  private String token;
+
+  private static final String SERVICE = "AUTH_SERVICES";
 
-  @Value("${security.jwt.expiration-time}")
-  private long jwtExpiration;
+  public String getOwnInternalToken() {
+
+    // Si no hay token, no es valido o quedan 10 seg para caducar se genera otro
+    if (token == null || validate(token) == null ||
+        decodeToken(token).getTtl() <= 10) {
+      token = generateInternalToken(SERVICE);
+    }
+
+    return token;
 
-  public long getExpirationTime() {
-    return jwtExpiration;
+  }
+
+  public String generateInternalToken(String service) {
+    String email = service.toLowerCase() + "@internal.com";
+    Algorithm algorithm = Algorithm.HMAC256(secretKey);
+
+    return JWT
+        .create()
+
+        .withKeyId(kid)
+        .withIssuedAt(new Date())
+        .withExpiresAt(new Date(System.currentTimeMillis() + intJwtExpiration * 1000))
+
+        .withSubject(service)
+        .withAudience("INTERNAL")
+
+        // DATA
+        .withClaim("service", service)
+        .withClaim("email", email)
+
+        .sign(algorithm);
   }
 
   public String generateToken(User user) {
     Algorithm algorithm = Algorithm.HMAC256(secretKey);
+
     return JWT
         .create()
+
         .withKeyId(kid)
+        .withIssuedAt(new Date())
+        .withExpiresAt(new Date(System.currentTimeMillis() + extJwtExpiration * 1000))
+
+        .withSubject(SERVICE)
+        .withAudience("EXTERNAL")
+
+        // DATA
         .withClaim("id", user.getId())
         .withClaim("name", user.getName())
         .withClaim("email", user.getEmail())
         .withClaim("rol", user.getRol().toString())
-        .withIssuedAt(new Date())
-        .withExpiresAt(new Date(System.currentTimeMillis() + jwtExpiration * 1000))
+
         .sign(algorithm);
   }
 
-  // TODO estaría guapo recuperar métodos de validación para el token de petición
-  // para este servicio
+  public DecodedJWT validate(String token) {
+    try {
+      return JWT.require(Algorithm.HMAC256(secretKey)).build().verify(token);
+    } catch (Exception e) {
+      return null;
+    }
+  }
+
+  public TokenData decodeToken(String token) {
+    DecodedJWT decoded = validate(token);
+    if (decoded == null)
+      return null;
+    return new TokenData(decoded, calculateTTL(decoded));
+  }
+
+  private long calculateTTL(DecodedJWT decodedJWT) {
+    if (decodedJWT == null)
+      throw new HttpClientErrorException(HttpStatus.FORBIDDEN);
+
+    long exp = decodedJWT.getExpiresAt().toInstant().getEpochSecond();
+    long now = Instant.now().getEpochSecond();
+
+    return exp - now;
+  }
+
 }
diff --git a/java/services/auth/src/main/resources/application.properties b/java/services/auth/src/main/resources/application.properties
index c9d72501a6b64ab7f91a39562614adfa601ef98e..ad4a9a515522af4efcda2a87f59dc1902879136f 100644
--- a/java/services/auth/src/main/resources/application.properties
+++ b/java/services/auth/src/main/resources/application.properties
@@ -3,7 +3,8 @@ server.port=8101
 
 security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
 # 1h in millisecond
-security.jwt.expiration-time=3600000 
+security.jwt.external.expiration=3600 
+security.jwt.internal.expiration=20
 security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
 
 external.services.users.url=http://localhost:8201/users
\ No newline at end of file
diff --git a/java/services/bookings/src/main/java/com/uva/apis/bookings/api/ClientApi.java b/java/services/bookings/src/main/java/com/uva/apis/bookings/api/ClientApi.java
index 470ddcff6aa8f7d959d4f20722221eb3e14397fd..c0333cb24ec5d41fceb703fa6c0d9d3e35662b58 100644
--- a/java/services/bookings/src/main/java/com/uva/apis/bookings/api/ClientApi.java
+++ b/java/services/bookings/src/main/java/com/uva/apis/bookings/api/ClientApi.java
@@ -17,7 +17,7 @@ public class ClientApi {
   private String CLIENTS_API_URL;
 
   public boolean existsById(int id) {
-    String url = CLIENTS_API_URL + "/{id}";
+    String url = CLIENTS_API_URL + "/" + id;
     ResponseEntity<Void> response = restTemplate.getForEntity(url, Void.class, id);
     return response.getStatusCode() == HttpStatus.OK;
   }
diff --git a/java/services/bookings/src/main/java/com/uva/apis/bookings/controllers/BookingController.java b/java/services/bookings/src/main/java/com/uva/apis/bookings/controllers/BookingController.java
index 44ee237a73f601bfd4104774866cf6388555a41c..597c657f9d4fed32aa5f3b82a7bf0c44fe5b0203 100644
--- a/java/services/bookings/src/main/java/com/uva/apis/bookings/controllers/BookingController.java
+++ b/java/services/bookings/src/main/java/com/uva/apis/bookings/controllers/BookingController.java
@@ -2,6 +2,7 @@ package com.uva.apis.bookings.controllers;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
@@ -39,12 +40,27 @@ public class BookingController {
         return bookingService.getBookingById(id);
     }
 
-    @DeleteMapping /// ?hotelId={hotelId}
-    public ResponseEntity<Void> deleteBooking(@RequestParam int hotelId) {
+    @DeleteMapping /// ?hotelId={hotelId}|managerId={managerId}
+    public ResponseEntity<?> deleteBooking(
+            @RequestParam(required = false) Integer hotelId,
+            @RequestParam(required = false) Integer managerId) {
         try {
-            bookingService.deleteBookingsByHotelId(hotelId);
-            return new ResponseEntity<>(HttpStatus.ACCEPTED);
+            List<Booking> bookings;
+            String message;
+            if (managerId != null) {
+                bookings = bookingService.deleteAllByManagerId(managerId);
+                message = "No bookings for this manager";
+            } else if (hotelId != null) {
+                bookings = bookingService.deleteBookingsByHotelId(hotelId);
+                message = "No bookings for this hotel";
+            } else {
+                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+            }
+            return !bookings.isEmpty()
+                    ? new ResponseEntity<>(bookings, HttpStatus.OK)
+                    : new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
         } catch (RuntimeException e) {
+            e.printStackTrace(System.err);
             return new ResponseEntity<>(HttpStatus.NOT_FOUND);
         }
     }
diff --git a/java/services/bookings/src/main/java/com/uva/apis/bookings/models/Booking.java b/java/services/bookings/src/main/java/com/uva/apis/bookings/models/Booking.java
index 8af8688534991b81c0b2b79aa01344bd5b2b86fa..fee28fd4b673f11db95d7b6296e5faee21cadd8d 100644
--- a/java/services/bookings/src/main/java/com/uva/apis/bookings/models/Booking.java
+++ b/java/services/bookings/src/main/java/com/uva/apis/bookings/models/Booking.java
@@ -31,6 +31,9 @@ public class Booking {
     @Column(name = "user_id", nullable = false)
     private int userId;
 
+    @Column(name = "manager_id", nullable = false)
+    private int managerId;
+
     @Column(name = "hotel_id", nullable = false)
     private int hotelId;
 
diff --git a/java/services/bookings/src/main/java/com/uva/apis/bookings/repositories/BookingRepository.java b/java/services/bookings/src/main/java/com/uva/apis/bookings/repositories/BookingRepository.java
index 646fa074709a0c14dd109c579d624f5ce20245e2..678b67eb4ad17734c90d10d3d74430991acec01d 100644
--- a/java/services/bookings/src/main/java/com/uva/apis/bookings/repositories/BookingRepository.java
+++ b/java/services/bookings/src/main/java/com/uva/apis/bookings/repositories/BookingRepository.java
@@ -10,6 +10,8 @@ import org.springframework.data.repository.query.Param;
 
 import com.uva.apis.bookings.models.Booking;
 
+import jakarta.transaction.Transactional;
+
 public interface BookingRepository extends JpaRepository<Booking, Integer> {
 
         List<Booking> findByUserId(int userId);
@@ -26,8 +28,14 @@ public interface BookingRepository extends JpaRepository<Booking, Integer> {
 
         void deleteById(int id);
 
+        @Transactional
         void deleteAllByHotelId(int hotelId);
 
         List<Booking> findByHotelId(Integer roomId);
 
+        @Transactional
+        void deleteAllByManagerId(int managerId);
+
+        List<Booking> findByManagerId(int managerId);
+
 }
diff --git a/java/services/bookings/src/main/java/com/uva/apis/bookings/services/BookingService.java b/java/services/bookings/src/main/java/com/uva/apis/bookings/services/BookingService.java
index 8d9425c87d1ead527a7b7c22040f4cbc7aa9577a..161a43540baa4f9ddc977ce48c13b1f03bf05c3e 100644
--- a/java/services/bookings/src/main/java/com/uva/apis/bookings/services/BookingService.java
+++ b/java/services/bookings/src/main/java/com/uva/apis/bookings/services/BookingService.java
@@ -11,6 +11,7 @@ import com.uva.apis.bookings.models.Booking;
 import com.uva.apis.bookings.repositories.BookingRepository;
 
 import java.time.LocalDate;
+import java.util.ArrayList;
 import java.util.List;
 
 @Service
@@ -117,8 +118,22 @@ public class BookingService {
         bookingRepository.deleteById(id);
     }
 
-    public void deleteBookingsByHotelId(int hotelId) {
+    public List<Booking> deleteBookingsByHotelId(int hotelId) {
         // Extraer reservas realizadas al hotel
+        List<Booking> bookings = bookingRepository.findByHotelId(hotelId);
+        if (bookings.isEmpty()) {
+            return new ArrayList<>();
+        }
         bookingRepository.deleteAllByHotelId(hotelId);
+        return bookings;
+    }
+
+    public List<Booking> deleteAllByManagerId(int managerId) {
+        List<Booking> bookings = bookingRepository.findByManagerId(managerId);
+        if (bookings.isEmpty()) {
+            return new ArrayList<>();
+        }
+        bookingRepository.deleteAllByManagerId(managerId);
+        return bookings;
     }
 }
diff --git a/java/services/bookings/src/main/resources/application.properties b/java/services/bookings/src/main/resources/application.properties
index 9ea8ffad1265e6413ef92d11b6787e8d891ef811..2731e248d85507dc8440a1341f0de987f8127527 100644
--- a/java/services/bookings/src/main/resources/application.properties
+++ b/java/services/bookings/src/main/resources/application.properties
@@ -14,5 +14,5 @@ security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
 security.jwt.expiration-time=3600000 
 security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
 
-external.services.clients.url=localhost:8201/users/clients
-external.services.hotels.url=localhost:8301/hotels
\ No newline at end of file
+external.services.clients.url=http://localhost:8201/users/clients
+external.services.hotels.url=http://localhost:8301/hotels
\ No newline at end of file
diff --git a/java/services/hotels/src/main/java/com/uva/monolith/api/BookingAPI.java b/java/services/hotels/src/main/java/com/uva/monolith/api/BookingAPI.java
index 0630e49ca97e40d6ad2eafc4c7e802b2a4f02e3a..369066bd537e131c333b04ae0415f7527cff6885 100644
--- a/java/services/hotels/src/main/java/com/uva/monolith/api/BookingAPI.java
+++ b/java/services/hotels/src/main/java/com/uva/monolith/api/BookingAPI.java
@@ -45,4 +45,9 @@ public class BookingAPI {
 
     return notAvailableRooms;
   }
+
+  public void deleteAllByManagerId(Integer managerId) {
+    String url = BOOKING_API_URL + "?managerId={managerId}";
+    restTemplate.delete(url, managerId);
+  }
 }
\ No newline at end of file
diff --git a/java/services/hotels/src/main/java/com/uva/monolith/api/HotelManagerAPI.java b/java/services/hotels/src/main/java/com/uva/monolith/api/ManagerAPI.java
similarity index 73%
rename from java/services/hotels/src/main/java/com/uva/monolith/api/HotelManagerAPI.java
rename to java/services/hotels/src/main/java/com/uva/monolith/api/ManagerAPI.java
index f4b0c18bb3fdfbadd919807368121500b92153ce..fda96949c48eb0cd159fd181efe6c845eff08767 100644
--- a/java/services/hotels/src/main/java/com/uva/monolith/api/HotelManagerAPI.java
+++ b/java/services/hotels/src/main/java/com/uva/monolith/api/ManagerAPI.java
@@ -1,7 +1,5 @@
 package com.uva.monolith.api;
 
-import java.util.Map;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpStatus;
@@ -9,8 +7,10 @@ import org.springframework.stereotype.Component;
 import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.RestTemplate;
 
+import com.fasterxml.jackson.databind.JsonNode;
+
 @Component
-public class HotelManagerAPI {
+public class ManagerAPI {
 
   @Autowired
   private RestTemplate restTemplate;
@@ -18,11 +18,12 @@ public class HotelManagerAPI {
   @Value("${external.services.managers.url}")
   private String MANAGERS_API_URL;
 
-  public Boolean existsHotelManagerById(int id) {
+  public Boolean existsManagerById(int id) {
     try {
       String url = MANAGERS_API_URL + "/{id}";
-      return restTemplate.getForObject(url, Map.class, id).containsKey("id");
+      return restTemplate.getForEntity(url, JsonNode.class, id).getStatusCode() == HttpStatus.OK;
     } catch (HttpClientErrorException e) {
+      e.printStackTrace(System.err);
       if (e.getStatusCode() != HttpStatus.NOT_FOUND)
         throw e;
       return false;
diff --git a/java/services/hotels/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java b/java/services/hotels/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
index 39c1b314c15ad3f49a9fad76dde88f45cc9b7458..de293524b54a865ab0d58a9877936cd8aa4145d0 100644
--- a/java/services/hotels/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
+++ b/java/services/hotels/src/main/java/com/uva/monolith/services/hotels/controllers/HotelController.java
@@ -12,7 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import com.uva.monolith.api.BookingAPI;
-import com.uva.monolith.api.HotelManagerAPI;
+import com.uva.monolith.api.ManagerAPI;
 import com.uva.monolith.exceptions.HotelNotFoundException;
 import com.uva.monolith.exceptions.InvalidDateRangeException;
 import com.uva.monolith.exceptions.InvalidRequestException;
@@ -32,7 +32,7 @@ public class HotelController {
     @Autowired
     private BookingAPI bookingAPI;
     @Autowired
-    private HotelManagerAPI hotelManagerAPI;
+    private ManagerAPI managerAPI;
 
     // Obtener todos los hoteles
     @GetMapping
@@ -62,13 +62,19 @@ public class HotelController {
     // Añadir un hotel con sus habitaciones
     @PostMapping
     public ResponseEntity<?> addHotel(@RequestBody Hotel hotel) {
-        boolean exist = hotelManagerAPI.existsHotelManagerById(hotel.getManagerId());
-        if (!exist) {
-            return new ResponseEntity<>(
-                    "No existe el manager con id " + String.valueOf(hotel.getManagerId()), HttpStatus.BAD_REQUEST);
+        try {
+
+            boolean exist = managerAPI.existsManagerById(hotel.getManagerId());
+            String message = "No existe el manager con id " + String.valueOf(hotel.getManagerId());
+            if (!exist) {
+                return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
+            }
+            Hotel savedHotel = hotelRepository.save(hotel);
+            return new ResponseEntity<>(savedHotel, HttpStatus.CREATED);
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+            throw e;
         }
-        Hotel savedHotel = hotelRepository.save(hotel);
-        return new ResponseEntity<>(savedHotel, HttpStatus.CREATED);
     }
 
     // Obtener un hotel por su ID
@@ -78,6 +84,19 @@ public class HotelController {
                 .orElseThrow(() -> new HotelNotFoundException(id));
     }
 
+    // Borrar hoteles administrados por un manager concreto
+    @DeleteMapping
+    public ResponseEntity<?> deleteHotelsByManagerId(
+            @RequestParam(required = true) Integer managerId) {
+        List<Hotel> hotels = hotelRepository.findAllByManagerId(managerId);
+        if (hotels.isEmpty()) {
+            return new ResponseEntity<>("No hay hoteles para el manager con id " + managerId, HttpStatus.BAD_REQUEST);
+        }
+        bookingAPI.deleteAllByManagerId(managerId);
+        hotelRepository.deleteAll(hotels);
+        return new ResponseEntity<>(hotels, HttpStatus.OK);
+    }
+
     // Borrar un hotel junto con sus habitaciones (borrado en cascada)
     @DeleteMapping("/{id}")
     @Transactional
diff --git a/java/services/users/pom.xml b/java/services/users/pom.xml
index 0eca2504ee970c5403bc3a785fa7003c78f82c8e..9ed5a3ede8fd48e11b7b74bba7499f2e5f6d13a5 100644
--- a/java/services/users/pom.xml
+++ b/java/services/users/pom.xml
@@ -52,11 +52,6 @@
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-security</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>com.auth0</groupId>
-			<artifactId>java-jwt</artifactId>
-			<version>4.4.0</version>
-		</dependency>
 		<dependency>
 			<groupId>jakarta.servlet</groupId>
 			<artifactId>jakarta.servlet-api</artifactId>
diff --git a/java/services/users/src/main/java/com/uva/api/apis/BookingAPI.java b/java/services/users/src/main/java/com/uva/api/apis/BookingAPI.java
index 6dad693f2215a1b0c0614e2d99a7ecb3ca88227a..aafffb5094fa3cf1fad685bdb02b889ffbc107e9 100644
--- a/java/services/users/src/main/java/com/uva/api/apis/BookingAPI.java
+++ b/java/services/users/src/main/java/com/uva/api/apis/BookingAPI.java
@@ -16,17 +16,19 @@ public class BookingAPI {
   @Autowired
   private RestTemplate restTemplate;
 
-  @Value("${external.services.bookings.url}")
+  @Value("${services.external.bookings.url}")
   private String BOOKING_API_URL;
 
-  public List<Booking> getAllBookingsByUserId(int id) {
+  public void deleteAllByUserId(int id) {
     String url = BOOKING_API_URL + "?userId={id}";
+    restTemplate.delete(url, id);
+  }
 
-    Booking[] bookingsArray = restTemplate
-        .getForObject(url, Booking[].class, id);
-
-    return Arrays.asList(bookingsArray);
+  public List<Booking> getAllByUserId(int id) {
+    String url = BOOKING_API_URL + "?userId={id}";
+    Booking[] bookings = restTemplate.getForObject(url, Booking[].class, id);
 
+    return Arrays.asList(bookings);
   }
 
 }
diff --git a/java/services/users/src/main/java/com/uva/api/apis/HotelApi.java b/java/services/users/src/main/java/com/uva/api/apis/HotelApi.java
index f6e3899272a2d5e16a3d474c904276ef80ab787d..c6541c58c931cfba57ecc717e1c43bea8fd64a40 100644
--- a/java/services/users/src/main/java/com/uva/api/apis/HotelApi.java
+++ b/java/services/users/src/main/java/com/uva/api/apis/HotelApi.java
@@ -1,5 +1,21 @@
 package com.uva.api.apis;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
 public class HotelApi {
 
+  @Autowired
+  private RestTemplate restTemplate;
+
+  @Value("${services.external.hotels.url}")
+  private String HOTELS_API;
+
+  public void deleteAllByManagerId(Integer id) {
+    String url = HOTELS_API + "?managerId={id}";
+    restTemplate.delete(url, id);
+  }
 }
diff --git a/java/services/users/src/main/java/com/uva/api/apis/TokenAPI.java b/java/services/users/src/main/java/com/uva/api/apis/TokenAPI.java
new file mode 100644
index 0000000000000000000000000000000000000000..01941ad762dfdfc3128583d0de2d4680d41b480f
--- /dev/null
+++ b/java/services/users/src/main/java/com/uva/api/apis/TokenAPI.java
@@ -0,0 +1,44 @@
+package com.uva.api.apis;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.uva.api.models.remote.JwtData;
+
+@Component
+public class TokenAPI {
+
+  @Autowired
+  private RestTemplate restTemplate;
+
+  @Value("${spring.application.name}")
+  private String service;
+
+  @Value("${services.internal.token.url}")
+  private String TOKEN_API_URL;
+
+  public JwtData getServiceToken() {
+    String url = TOKEN_API_URL + "/service";
+    Map<String, String> body = new HashMap<>();
+    body.put("service", service);
+    String token = restTemplate.postForObject(url, body, JsonNode.class)
+        .get("token").asText();
+    return decodeToken(token);
+  }
+
+  public JwtData decodeToken(String token) {
+    String url = TOKEN_API_URL + "/info";
+    Map<String, String> body = new HashMap<>();
+    body.put("token", token);
+    JwtData response = restTemplate.postForObject(url, body, JwtData.class);
+    response.setToken(token);
+    return response;
+  }
+
+}
diff --git a/java/services/users/src/main/java/com/uva/api/config/RestTemplateInterceptor.java b/java/services/users/src/main/java/com/uva/api/config/RestTemplateInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a6e85f4c3fcfa7d8ce890130417e5807a9124ce
--- /dev/null
+++ b/java/services/users/src/main/java/com/uva/api/config/RestTemplateInterceptor.java
@@ -0,0 +1,31 @@
+package com.uva.api.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.stereotype.Component;
+
+import com.uva.api.services.TokenService;
+
+import java.io.IOException;
+
+@Component
+public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
+
+  @Autowired
+  private TokenService service;
+
+  @Override
+  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
+      throws IOException {
+
+    String jwtToken = service.getServiceToken();
+    System.out.println("Using token " + jwtToken);
+
+    request.getHeaders().add("Authorization", "Bearer " + jwtToken);
+
+    return execution.execute(request, body);
+  }
+}
diff --git a/java/services/users/src/main/java/com/uva/api/config/SecurityConfig.java b/java/services/users/src/main/java/com/uva/api/config/SecurityConfig.java
index 5aa0f6e0f22a1b524146320a77777881415510c9..d9720e394866dadef3daa91b42a659cf01d25885 100644
--- a/java/services/users/src/main/java/com/uva/api/config/SecurityConfig.java
+++ b/java/services/users/src/main/java/com/uva/api/config/SecurityConfig.java
@@ -23,32 +23,32 @@ public class SecurityConfig {
 
   @Bean
   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.CLIENT.toString(),
-    // UserRol.HOTEL_ADMIN.toString(),
-    // UserRol.ADMIN.toString())
-    // // Acceso restringido a gestores de hoteles y administradores
-    // .requestMatchers(HttpMethod.GET, "hotels", "hotels/*").hasAnyRole(
-    // UserRol.CLIENT.toString(),
-    // UserRol.HOTEL_ADMIN.toString(),
-    // UserRol.ADMIN.toString())
-
-    // .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);
+    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.CLIENT.toString(),
+        // UserRol.HOTEL_ADMIN.toString(),
+        // UserRol.ADMIN.toString())
+        // // Acceso restringido a gestores de hoteles y administradores
+        // .requestMatchers(HttpMethod.GET, "hotels", "hotels/*").hasAnyRole(
+        // UserRol.CLIENT.toString(),
+        // UserRol.HOTEL_ADMIN.toString(),
+        // UserRol.ADMIN.toString())
+
+        // .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/api/controllers/ClientController.java b/java/services/users/src/main/java/com/uva/api/controllers/ClientController.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0e50a3661aaa6719805f8964aca782d8a39f0d7
--- /dev/null
+++ b/java/services/users/src/main/java/com/uva/api/controllers/ClientController.java
@@ -0,0 +1,69 @@
+package com.uva.api.controllers;
+
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.HttpClientErrorException;
+
+import com.uva.api.models.ClientStatus;
+import com.uva.api.services.ClientService;
+
+@RestController
+@RequestMapping("users/clients")
+@CrossOrigin(origins = "*")
+public class ClientController {
+
+  @Autowired
+  private ClientService clientService;
+
+  // Clients
+  @GetMapping
+  public ResponseEntity<?> getAllClients() {
+    return clientService.findAll();
+  }
+
+  @GetMapping("/{id}")
+  public ResponseEntity<?> getClientById(@PathVariable int id) {
+    return clientService.findById(id);
+  }
+
+  @PatchMapping("/{id}")
+  public ResponseEntity<?> updateClientState(@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 {
+      ClientStatus clientStatus = ClientStatus.valueOf(strStatus);
+      return ResponseEntity.ok(clientService.updateClientStatus(id, clientStatus));
+    } catch (IllegalArgumentException e) {
+      return new ResponseEntity<String>("Unknown Client 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<?> deleteClient(@PathVariable Integer id) {
+    try {
+      return ResponseEntity.ok(clientService.deleteById(id));
+    } catch (HttpClientErrorException e) {
+      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
+        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
+      throw e;
+    }
+  }
+}
diff --git a/java/services/users/src/main/java/com/uva/api/controllers/ManagerController.java b/java/services/users/src/main/java/com/uva/api/controllers/ManagerController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5af94d7079356035a34268b2f0e7d7067969fd7
--- /dev/null
+++ b/java/services/users/src/main/java/com/uva/api/controllers/ManagerController.java
@@ -0,0 +1,48 @@
+package com.uva.api.controllers;
+
+import java.util.List;
+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.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.HttpClientErrorException;
+
+import com.uva.api.models.Manager;
+import com.uva.api.services.ManagerService;
+
+@RestController
+@RequestMapping("users/managers")
+@CrossOrigin(origins = "*")
+public class ManagerController {
+
+  @Autowired
+  private ManagerService managerService;
+
+  @GetMapping
+  public ResponseEntity<List<Manager>> getAllHotelManagers() {
+    List<Manager> users = managerService.findAll();
+    return ResponseEntity.ok(users);
+  }
+
+  @GetMapping("/{id}")
+  public ResponseEntity<Manager> getHotelManagerById(@PathVariable Integer id) {
+    return ResponseEntity.ok(managerService.findById(id));
+  }
+
+  @DeleteMapping("/{id}")
+  public ResponseEntity<?> deleteHotelManager(@PathVariable Integer id) {
+    try {
+      return ResponseEntity.ok(managerService.deleteById(id));
+    } catch (HttpClientErrorException e) {
+      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
+        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
+      throw e;
+    }
+  }
+
+}
diff --git a/java/services/users/src/main/java/com/uva/api/controllers/UserController.java b/java/services/users/src/main/java/com/uva/api/controllers/UserController.java
index 121670cb98bb3e26a6e9f49b3d5914d70f0b3863..38cae78c05aac1345b7ee2121f658f639d68c6cc 100644
--- a/java/services/users/src/main/java/com/uva/api/controllers/UserController.java
+++ b/java/services/users/src/main/java/com/uva/api/controllers/UserController.java
@@ -1,16 +1,13 @@
 package com.uva.api.controllers;
 
-import java.util.List;
 import java.util.Map;
 
-import org.springframework.beans.BeanUtils;
 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;
@@ -18,16 +15,8 @@ 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.fasterxml.jackson.databind.JsonNode;
-import com.uva.api.models.AuthResponse;
-import com.uva.api.models.Client;
-import com.uva.api.models.Manager;
-import com.uva.api.models.User;
-import com.uva.api.models.ClientStatus;
-import com.uva.api.services.ClientService;
-import com.uva.api.services.ManagerService;
+import com.uva.api.models.AuthDTO;
 import com.uva.api.services.UserService;
 import com.uva.api.utils.Utils;
 
@@ -39,19 +28,9 @@ public class UserController {
   @Autowired
   private UserService userService;
 
-  @Autowired
-  private ClientService clientService;
-
-  @Autowired
-  private ManagerService managerService;
-
-  // Common
   @PostMapping
-  public ResponseEntity<?> addUser(@RequestBody AuthResponse body) {
-    User user = new User();
-    BeanUtils.copyProperties(body, user);
-    userService.registerNewUser(user);
-    return new ResponseEntity<User>(user, HttpStatus.ACCEPTED);
+  public ResponseEntity<?> addUser(@RequestBody AuthDTO body) {
+    return userService.registerNewUser(body);
   }
 
   @PutMapping("/{id}")
@@ -63,14 +42,8 @@ public class UserController {
     if (!Utils.notEmptyStrings(name, email)) {
       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;
-    }
+
+    return userService.updateUserData(id, name, email);
   }
 
   @PutMapping("/{id}/password")
@@ -81,112 +54,67 @@ public class UserController {
       return new ResponseEntity<String>("Missing required fields", HttpStatus.BAD_REQUEST);
     }
 
-    try {
-      User user = userService.changePassword(id, password);
-      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;
-    }
+    return userService.changePassword(id, password);
   }
 
+  // TODO aplicarr verificación
+  // @Autowired
+  // private TokenService ser;
+
+  // private String validate(String token) {
+  // JWTData decoded = ser.decodeToken(token);
+  // if (decoded == null) {
+  // return "Invalid token format";
+  // }
+  // UserRol rol = decoded.getRol();
+  // String audience = decoded.getAudience();
+  // boolean a = (rol == null || rol != UserRol.ADMIN);
+  // boolean b = (audience == null || !audience.equals("INTERNAL"));
+  // if (a && b) {
+  // return "Invalid " + a + " " + b;
+  // }
+  // return null;
+
+  // }
+
+  // @GetMapping(params = { "email" })
+  // public ResponseEntity<?> getUserByEmail(@RequestParam String email,
+  // @RequestHeader(value = "Authorization", required = true) String
+  // authorization) {
+  // try {
+  // if (authorization == null) {
+  // return new ResponseEntity<String>("Missing required fields",
+  // HttpStatus.BAD_REQUEST);
+  // }
+  // String m = validate(authorization.substring(7));
+  // if (m != null) {
+  // return new ResponseEntity<String>(m, HttpStatus.BAD_REQUEST);
+  // }
+  // return ResponseEntity.ok(userService.getUserByEmail(email));
+  // } catch (HttpClientErrorException e) {
+  // if (e.getStatusCode() == HttpStatus.NOT_FOUND)
+  // return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
+  // throw e;
+  // }
+  // }
+
   @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;
-    }
+    return userService.getUserByEmail(email);
   }
 
   @GetMapping
-  public ResponseEntity<List<User>> getAllUsers() {
-    List<User> users = userService.getAllUsers();
-    return ResponseEntity.ok(users);
+  public ResponseEntity<?> getAllUsers() {
+    return userService.getAllUsers();
   }
 
   @GetMapping("/{id}")
   public ResponseEntity<?> getUserById(@PathVariable int id) {
-    return ResponseEntity.ok(userService.getUserById(id));
+    return userService.getUserById(id);
   }
 
   @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;
-    }
-  }
-
-  // Clients
-  @GetMapping("/clients")
-  public ResponseEntity<List<Client>> getAllClients() {
-    List<Client> users = clientService.findAll();
-    return ResponseEntity.ok(users);
-  }
-
-  @GetMapping("/clients/{id}")
-  public ResponseEntity<Client> getClientById(@PathVariable int id) {
-    return ResponseEntity.ok(clientService.findById(id));
-  }
-
-  @PatchMapping("/clients/{id}")
-  public ResponseEntity<?> updateClientState(@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 {
-      ClientStatus clientStatus = ClientStatus.valueOf(strStatus);
-      return ResponseEntity.ok(clientService.updateClientStatus(id, clientStatus));
-    } catch (IllegalArgumentException e) {
-      return new ResponseEntity<String>("Unknown Client state", HttpStatus.BAD_REQUEST);
-    } catch (HttpClientErrorException e) {
-      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
-        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
-      throw e;
-    }
-  }
-
-  @DeleteMapping("/clients/{id}")
-  public ResponseEntity<?> deleteClient(@PathVariable Integer id) {
-    try {
-      return ResponseEntity.ok(clientService.deleteById(id));
-    } catch (HttpClientErrorException e) {
-      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
-        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
-      throw e;
-    }
+  public ResponseEntity<?> deleteUser(@PathVariable int id) {
+    return userService.deleteUserById(id);
   }
-
-  // HotelManagers
-  @GetMapping("/managers")
-  public ResponseEntity<List<Manager>> getAllHotelManagers() {
-    List<Manager> users = managerService.findAll();
-    return ResponseEntity.ok(users);
-  }
-
-  @GetMapping("/managers/{id}")
-  public ResponseEntity<Manager> getHotelManagerById(@PathVariable int id) {
-    return ResponseEntity.ok(managerService.findById(id));
-  }
-
-  @DeleteMapping("/managers/{id}")
-  public ResponseEntity<?> deleteHotelManager(@PathVariable Integer id) {
-    try {
-      return ResponseEntity.ok(managerService.deleteById(id));
-    } catch (HttpClientErrorException e) {
-      if (e.getStatusCode() == HttpStatus.NOT_FOUND)
-        return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
-      throw e;
-    }
-  }
-
 }
diff --git a/java/services/users/src/main/java/com/uva/api/exceptions/GlobalExceptionHandler.java b/java/services/users/src/main/java/com/uva/api/exceptions/GlobalExceptionHandler.java
index 5681a607c7b0885255a2259e809cb4bb29bf456d..426b2fb250097e33499079693c456069dabc801c 100644
--- a/java/services/users/src/main/java/com/uva/api/exceptions/GlobalExceptionHandler.java
+++ b/java/services/users/src/main/java/com/uva/api/exceptions/GlobalExceptionHandler.java
@@ -12,8 +12,8 @@ import java.util.Map;
 @ControllerAdvice
 public class GlobalExceptionHandler {
 
-    @ExceptionHandler(HotelNotFoundException.class)
-    public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
+    @ExceptionHandler(UserNotFoundException.class)
+    public ResponseEntity<Map<String, Object>> handleUserNotFound(UserNotFoundException ex) {
         Map<String, Object> body = new HashMap<>();
         body.put("timestamp", LocalDateTime.now());
         body.put("message", ex.getMessage());
@@ -21,24 +21,6 @@ public class GlobalExceptionHandler {
         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<>();
diff --git a/java/services/users/src/main/java/com/uva/api/exceptions/InvalidDateRangeException.java b/java/services/users/src/main/java/com/uva/api/exceptions/InvalidDateRangeException.java
deleted file mode 100644
index 58bf97d7b6dceb1db771de7058da6f159480a5b9..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/api/exceptions/InvalidDateRangeException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.uva.api.exceptions;
-
-public class InvalidDateRangeException extends RuntimeException {
-    public InvalidDateRangeException(String message) {
-        super(message);
-    }
-}
diff --git a/java/services/users/src/main/java/com/uva/api/exceptions/InvalidRequestException.java b/java/services/users/src/main/java/com/uva/api/exceptions/InvalidRequestException.java
deleted file mode 100644
index 677cc4b7cb71bb20c3a9644ff2a8d3552546ea2c..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/api/exceptions/InvalidRequestException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.uva.api.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/api/exceptions/HotelNotFoundException.java b/java/services/users/src/main/java/com/uva/api/exceptions/UserNotFoundException.java
similarity index 60%
rename from java/services/users/src/main/java/com/uva/api/exceptions/HotelNotFoundException.java
rename to java/services/users/src/main/java/com/uva/api/exceptions/UserNotFoundException.java
index dc466f6f5f91da47dbe73c34b97059c817937f13..9d12fb2fe156607f5558986e92d513f85b386d6c 100644
--- a/java/services/users/src/main/java/com/uva/api/exceptions/HotelNotFoundException.java
+++ b/java/services/users/src/main/java/com/uva/api/exceptions/UserNotFoundException.java
@@ -4,8 +4,8 @@ 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);
+public class UserNotFoundException extends RuntimeException {
+    public UserNotFoundException(int id) {
+        super("User not found with id: " + id);
     }
 }
diff --git a/java/services/users/src/main/java/com/uva/api/filter/JwtAuthenticationFilter.java b/java/services/users/src/main/java/com/uva/api/filter/JwtAuthenticationFilter.java
index a68cb2098ad5b2002c208e7a3ccbb1bdbfbd26f5..18ef31e44129a2333fdbf7d90b52e9c908e02c8c 100644
--- a/java/services/users/src/main/java/com/uva/api/filter/JwtAuthenticationFilter.java
+++ b/java/services/users/src/main/java/com/uva/api/filter/JwtAuthenticationFilter.java
@@ -1,12 +1,10 @@
 package com.uva.api.filter;
 
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.JWTVerifier;
-import com.auth0.jwt.algorithms.Algorithm;
-import com.auth0.jwt.interfaces.DecodedJWT;
 import com.uva.api.models.UserRol;
-import com.auth0.jwt.exceptions.JWTVerificationException;
+import com.uva.api.models.remote.JwtData;
+import com.uva.api.services.TokenService;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -19,21 +17,19 @@ import jakarta.servlet.ServletException;
 import jakarta.servlet.ServletRequest;
 import jakarta.servlet.ServletResponse;
 import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.Filter;
 
 import java.io.IOException;
 import java.time.LocalDateTime;
 import java.util.Collections;
+import java.util.Map;
 
 @Component
 public class JwtAuthenticationFilter implements Filter {
 
-    @Value("${security.jwt.secret-key}")
-    private String secretKey;
-
-    private Algorithm getSigningAlgorithm() {
-        return Algorithm.HMAC256(secretKey); // Usar HMAC256 con la clave secreta
-    }
+    @Autowired
+    private TokenService service;
 
     private String getTokenFromRequest(HttpServletRequest request) {
         String authHeader = request.getHeader("Authorization");
@@ -43,26 +39,17 @@ public class JwtAuthenticationFilter implements Filter {
         return authHeader.substring(7);
     }
 
-    private DecodedJWT validateAndDecodeToken(String token) {
+    private JwtData validateAndDecodeToken(String token) {
         try {
-            JWTVerifier verifier = JWT.require(getSigningAlgorithm()).build();
-            return verifier.verify(token); // Verifica y decodifica el token
-        } catch (JWTVerificationException ex) {
-            System.out.println(
-                    "[" + LocalDateTime.now().toString() + "] Error de verificación del token: " + ex.getMessage());
+            return service.decodeToken(token);
+        } catch (Exception ex) {
+            System.err.println(
+                    "[" + LocalDateTime.now().toString() + "] Error de verificación del token");
+            ex.printStackTrace(System.err);
             return null;
         }
     }
 
-    private String getEmailFromToken(DecodedJWT jwt) {
-        return jwt.getClaim("email").asString();
-    }
-
-    private UserRol getRoleFromToken(DecodedJWT jwt) {
-        String role = jwt.getClaim("rol").asString();
-        return UserRol.valueOf(role);
-    }
-
     private String formatRole(UserRol rol) {
         return String.format("ROLE_%s", rol.toString());
     }
@@ -70,34 +57,42 @@ public class JwtAuthenticationFilter implements Filter {
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
             throws IOException, ServletException {
+
         HttpServletRequest httpRequest = (HttpServletRequest) request;
         String token = getTokenFromRequest(httpRequest);
 
-        System.out.print("[" + LocalDateTime.now().toString() + "] TOKEN: " + token);
+        System.out.println("[" + LocalDateTime.now().toString() + "] TOKEN: " + token);
 
         if (token != null) {
-            DecodedJWT jwt = validateAndDecodeToken(token);
-            System.out.print(" " + jwt.toString() + " ");
+            JwtData jwt = validateAndDecodeToken(token);
             if (jwt != null) {
-                String email = getEmailFromToken(jwt);
-                UserRol role = getRoleFromToken(jwt);
-                System.out.print(" email=" + email + " role=" + role + " ");
-
-                if (email != null && role != null && SecurityContextHolder.getContext().getAuthentication() == null) {
-                    // Crear la autoridad con el rol del token
-                    SimpleGrantedAuthority authority = new SimpleGrantedAuthority(formatRole(role));
-
-                    // Crear autenticación
-                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(email,
-                            null, Collections.singletonList(authority));
-                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
-
-                    // Establecer autenticación en el contexto de seguridad
-                    SecurityContextHolder.getContext().setAuthentication(authentication);
-                }
+                System.out.println("-->" + jwt + "<--");
             }
         }
 
+        // String email = getEmailFromToken(jwt);
+        // UserRol role = getRoleFromToken(jwt);
+        // System.out.print(" email=" + email + " role=" + role + " ");
+
+        // if (email != null && role != null &&
+        // SecurityContextHolder.getContext().getAuthentication() == null) {
+        // // Crear la autoridad con el rol del token
+        // SimpleGrantedAuthority authority = new
+        // SimpleGrantedAuthority(formatRole(role));
+
+        // // Crear autenticación
+        // UsernamePasswordAuthenticationToken authentication = new
+        // UsernamePasswordAuthenticationToken(email,
+        // null, Collections.singletonList(authority));
+        // authentication.setDetails(new
+        // WebAuthenticationDetailsSource().buildDetails(httpRequest));
+
+        // // Establecer autenticación en el contexto de seguridad
+        // SecurityContextHolder.getContext().setAuthentication(authentication);
+        // }
+        // }
+        // }
+
         // Continuar con el resto de filtros
         chain.doFilter(request, response);
     }
diff --git a/java/services/users/src/main/java/com/uva/api/interceptor/AuthHttpInterceptor.java b/java/services/users/src/main/java/com/uva/api/interceptor/AuthHttpInterceptor.java
deleted file mode 100644
index 6e1a9256e6caf024c94dfd4ac49ab17cb982eb87..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/api/interceptor/AuthHttpInterceptor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.uva.api.interceptor;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpRequest;
-import org.springframework.http.client.ClientHttpRequestExecution;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.http.client.ClientHttpRequestInterceptor;
-import org.springframework.stereotype.Component;
-
-import com.uva.api.models.UserRol;
-import com.uva.api.utils.JwtUtil;
-
-import java.io.IOException;
-
-@Component
-public class AuthHttpInterceptor implements ClientHttpRequestInterceptor {
-
-  @Autowired
-  private JwtUtil jwtUtil;
-
-  private String token;
-
-  private String getAccessToken() {
-    if (token == null || token.isEmpty()) {
-      // TODO cambiar también si el token ha caducado
-      token = jwtUtil.generateToken("auth", "auth@dev.com", UserRol.ADMIN);
-    }
-    return token;
-
-  }
-
-  @Override
-  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
-      throws IOException {
-    // Generar o cargar el JWT token desde el bean JwtUtil
-    String jwtToken = getAccessToken();
-
-    // System.out.println("Using token " + jwtToken);
-
-    // Agregar el token al encabezado Authorization
-    request.getHeaders().add("Authorization", "Bearer " + jwtToken);
-
-    // Continuar con la ejecución de la solicitud
-    return execution.execute(request, body);
-  }
-}
diff --git a/java/services/users/src/main/java/com/uva/api/models/AuthResponse.java b/java/services/users/src/main/java/com/uva/api/models/AuthDTO.java
similarity index 82%
rename from java/services/users/src/main/java/com/uva/api/models/AuthResponse.java
rename to java/services/users/src/main/java/com/uva/api/models/AuthDTO.java
index ca8edf2a813699de08326948c55306d2dfbf567e..a340fc6852ccc45d1a608ad6a483e0851e88c1fa 100644
--- a/java/services/users/src/main/java/com/uva/api/models/AuthResponse.java
+++ b/java/services/users/src/main/java/com/uva/api/models/AuthDTO.java
@@ -9,11 +9,11 @@ import lombok.Setter;
 @AllArgsConstructor
 @Getter
 @Setter
-public class AuthResponse {
+public class AuthDTO {
 
   private int id;
   private String name;
   private String email;
   private String password;
-  private UserRol rol;
+  private UserRol rol = UserRol.CLIENT;
 }
diff --git a/java/services/users/src/main/java/com/uva/api/models/Client.java b/java/services/users/src/main/java/com/uva/api/models/Client.java
index 5205bebb8c355c5e9f65b1a7cb4d7c89d53b2a58..71f3a3f207782ca891acfa1cac513ec7fe9fb356 100644
--- a/java/services/users/src/main/java/com/uva/api/models/Client.java
+++ b/java/services/users/src/main/java/com/uva/api/models/Client.java
@@ -1,17 +1,14 @@
 package com.uva.api.models;
 
-import java.time.LocalDate;
 import java.util.List;
 
 import com.uva.api.models.remote.Booking;
 
-import jakarta.persistence.Basic;
 import jakarta.persistence.Column;
 import jakarta.persistence.Entity;
 import jakarta.persistence.EnumType;
 import jakarta.persistence.Enumerated;
 import jakarta.persistence.Table;
-import jakarta.persistence.Transient;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
@@ -29,29 +26,23 @@ import lombok.ToString;
 @EqualsAndHashCode(callSuper = true)
 public class Client extends User {
 
-  @Basic(optional = false)
   @Column(nullable = false)
   @Enumerated(EnumType.STRING)
   private ClientStatus status = ClientStatus.NO_BOOKINGS;
-  @Transient
-  private List<Booking> bookings;
 
   public Client(int id, String name, String email, String password, ClientStatus status,
       List<Booking> bookings) {
     super(id, name, email, password, UserRol.CLIENT);
     setStatus(status);
-    setBookings(bookings);
   }
 
-  public ClientStatus getStatus() {
-    if (getBookings() == null || getBookings().isEmpty())
-      return ClientStatus.NO_BOOKINGS;
-    boolean activeBookings = getBookings().stream()
-        .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora
-    return activeBookings ? ClientStatus.WITH_ACTIVE_BOOKINGS : ClientStatus.WITH_INACTIVE_BOOKINGS;
-  }
-
-  public void setStatus(ClientStatus status) {
-    this.status = status;
-  }
+  // public ClientStatus getStatus() {
+  // if (getBookings() == null || getBookings().isEmpty())
+  // return ClientStatus.NO_BOOKINGS;
+  // boolean activeBookings = getBookings().stream()
+  // .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); //
+  // reserva >= ahora
+  // return activeBookings ? ClientStatus.WITH_ACTIVE_BOOKINGS :
+  // ClientStatus.WITH_INACTIVE_BOOKINGS;
+  // }
 }
diff --git a/java/services/users/src/main/java/com/uva/api/models/Manager.java b/java/services/users/src/main/java/com/uva/api/models/Manager.java
index d0b1780186159691d8372adc561515b198e3a242..f72e762b13b73585534608c5e3be25b5ed623ba0 100644
--- a/java/services/users/src/main/java/com/uva/api/models/Manager.java
+++ b/java/services/users/src/main/java/com/uva/api/models/Manager.java
@@ -1,5 +1,6 @@
 package com.uva.api.models;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.databind.JsonNode;
 
 import jakarta.persistence.Entity;
@@ -23,6 +24,7 @@ import lombok.ToString;
 public class Manager extends User {
 
   @Transient
+  @JsonIgnore
   private JsonNode hotels;
 
   public Manager(int id, String name, String email, String password, JsonNode hotels) {
diff --git a/java/services/users/src/main/java/com/uva/api/models/remote/JwtData.java b/java/services/users/src/main/java/com/uva/api/models/remote/JwtData.java
new file mode 100644
index 0000000000000000000000000000000000000000..21774c76be754aacdb2005499b96591ce3459fd9
--- /dev/null
+++ b/java/services/users/src/main/java/com/uva/api/models/remote/JwtData.java
@@ -0,0 +1,36 @@
+package com.uva.api.models.remote;
+
+import java.util.Date;
+
+import com.uva.api.models.UserRol;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@Data
+@ToString
+public class JwtData {
+
+  private String token;
+
+  private Integer id;
+  private String name;
+  private String email;
+  private UserRol rol;
+  private String service;
+
+  private String subject;
+  private String audience;
+  private Long ttl;
+
+  private Date issuedAt;
+  private Date expiresAt;
+
+  public boolean isAdmin() {
+    return rol != null && rol == UserRol.ADMIN;
+  }
+}
\ No newline at end of file
diff --git a/java/services/users/src/main/java/com/uva/api/services/ClientService.java b/java/services/users/src/main/java/com/uva/api/services/ClientService.java
index c3f352300a3a531a6548310911e7f1512f273cdd..81d3f92c2f2cac8108da9263eca42d413118fc9d 100644
--- a/java/services/users/src/main/java/com/uva/api/services/ClientService.java
+++ b/java/services/users/src/main/java/com/uva/api/services/ClientService.java
@@ -5,14 +5,15 @@ import java.util.List;
 
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 
 import com.uva.api.apis.BookingAPI;
 import com.uva.api.models.Client;
 import com.uva.api.models.User;
 import com.uva.api.models.UserRol;
-import com.uva.api.models.ClientStatus;
 import com.uva.api.models.remote.Booking;
+import com.uva.api.models.ClientStatus;
 import com.uva.api.repositories.ClientRepository;
 import com.uva.api.utils.Utils;
 
@@ -25,19 +26,18 @@ public class ClientService {
   @Autowired
   private BookingAPI bookingAPI;
 
-  public List<Client> findAll() {
-    return clientRepository.findAll();
+  public ResponseEntity<?> findAll() {
+    return ResponseEntity.ok(clientRepository.findAll());
   }
 
-  public Client findById(int id) {
+  public ResponseEntity<?> findById(int id) {
     Client client = Utils.assertUser(clientRepository.findById(id));
-    List<Booking> bookings = bookingAPI.getAllBookingsByUserId(client.getId());
-    client.setBookings(bookings);
-    return client;
+    return ResponseEntity.ok(client);
   }
 
   public Client deleteById(int id) {
     Client client = Utils.assertUser(clientRepository.findById(id));
+    bookingAPI.deleteAllByUserId(id);
     clientRepository.delete(client);
     return client;
   }
@@ -50,27 +50,30 @@ public class ClientService {
     return clientRepository.save(client);
   }
 
+  // TODO No entiendo donde debería ir esto
   public User updateClientStatus(int id, ClientStatus status) {
     Client user = Utils.assertUser(clientRepository.findById(id));
 
-    boolean activeBookings = user.getBookings().stream()
+    List<Booking> bookings = bookingAPI.getAllByUserId(id);
+
+    boolean activeBookings = bookings.stream()
         .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora
-    boolean inactiveBookings = user.getBookings().stream()
+    boolean inactiveBookings = bookings.stream()
         .anyMatch(booking -> booking.getEndDate().isBefore(LocalDate.now())); // reserva < ahora
 
     switch (status) {
       case NO_BOOKINGS:
-        if (!user.getBookings().isEmpty())
+        if (!bookings.isEmpty())
           throw new IllegalArgumentException("Invalid State: The user has at least one booking");
         break;
       case WITH_ACTIVE_BOOKINGS:
-        if (user.getBookings().isEmpty())
+        if (bookings.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())
+        if (bookings.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");
diff --git a/java/services/users/src/main/java/com/uva/api/services/ManagerService.java b/java/services/users/src/main/java/com/uva/api/services/ManagerService.java
index 098fc043649d85383c5371d2f995f4a908bc63c3..87d8f38c546f2080522205927400a3dcaa42672b 100644
--- a/java/services/users/src/main/java/com/uva/api/services/ManagerService.java
+++ b/java/services/users/src/main/java/com/uva/api/services/ManagerService.java
@@ -6,6 +6,7 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import com.uva.api.apis.HotelApi;
 import com.uva.api.models.Manager;
 import com.uva.api.models.User;
 import com.uva.api.repositories.ManagerRepository;
@@ -14,6 +15,9 @@ import com.uva.api.utils.Utils;
 @Service
 public class ManagerService {
 
+  @Autowired
+  private HotelApi hotelApi;
+
   @Autowired
   private ManagerRepository managerRepository;
 
@@ -34,6 +38,7 @@ public class ManagerService {
 
   public Object deleteById(Integer id) {
     Manager manager = Utils.assertUser(managerRepository.findById(id));
+    hotelApi.deleteAllByManagerId(id);
     managerRepository.delete(manager);
     return manager;
   }
diff --git a/java/services/users/src/main/java/com/uva/api/services/TokenService.java b/java/services/users/src/main/java/com/uva/api/services/TokenService.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d90bbe4e3f3cecfa444d084c98b01c830163844
--- /dev/null
+++ b/java/services/users/src/main/java/com/uva/api/services/TokenService.java
@@ -0,0 +1,48 @@
+package com.uva.api.services;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.uva.api.apis.TokenAPI;
+import com.uva.api.models.remote.JwtData;
+
+@Service
+public class TokenService {
+
+  @Autowired
+  private TokenAPI api;
+
+  private JwtData ownToken;
+  private Map<String, JwtData> cache = new HashMap<>();
+
+  private boolean expireSoon(JwtData decoded) {
+    return (decoded.getExpiresAt().getTime() - System.currentTimeMillis()) / 1000 <= 10;
+  }
+
+  public String getServiceToken() {
+    if (ownToken == null || expireSoon(ownToken)) {
+      System.out.println("Generando token");
+      long s = System.currentTimeMillis();
+      ownToken = api.getServiceToken();
+      long t = System.currentTimeMillis() - s;
+      System.out.println("Token Generando en " + t + " ms");
+    }
+    return ownToken.getToken();
+  }
+
+  public JwtData decodeToken(String token) {
+    if (cache.containsKey(token))
+      return cache.get(token);
+    System.out.println("Actualizando token");
+    long s = System.currentTimeMillis();
+    JwtData decoded = api.decodeToken(token);
+    long t = System.currentTimeMillis() - s;
+    System.out.println("Actualizando token en " + t + " ms");
+    cache.put(token, decoded);
+    return decoded;
+  }
+
+}
diff --git a/java/services/users/src/main/java/com/uva/api/services/UserService.java b/java/services/users/src/main/java/com/uva/api/services/UserService.java
index deb2e39905bd7f2b6bc80c9eef4e7ae31eb90d01..99f21a10bdcbf39d24b18c16f453d8df5f3523a4 100644
--- a/java/services/users/src/main/java/com/uva/api/services/UserService.java
+++ b/java/services/users/src/main/java/com/uva/api/services/UserService.java
@@ -4,10 +4,10 @@ import java.util.List;
 
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
-
 import com.uva.api.utils.Utils;
-import com.uva.api.models.AuthResponse;
+import com.uva.api.models.AuthDTO;
 import com.uva.api.models.User;
 import com.uva.api.models.UserRol;
 import com.uva.api.repositories.UserRepository;
@@ -24,63 +24,83 @@ public class UserService {
   @Autowired
   private ManagerService managerService;
 
-  public List<User> getAllUsers() {
-    return userRepository.findAll();
+  public ResponseEntity<List<User>> getAllUsers() {
+    List<User> users = userRepository.findAll();
+    return ResponseEntity.ok(users);
   }
 
-  public User getUserById(int id) {
+  private User assertUserById(int id) {
     return Utils.assertUser(userRepository.findById(id));
   }
 
-  public AuthResponse getUserByEmail(String email) {
+  public ResponseEntity<User> getUserById(int id) {
+    User user = assertUserById(id);
+    return ResponseEntity.ok(user);
+  }
+
+  public ResponseEntity<AuthDTO> getUserByEmail(String email) {
     User u = Utils.assertUser(userRepository.findByEmail(email));
-    AuthResponse auth = new AuthResponse();
+    AuthDTO auth = new AuthDTO();
     BeanUtils.copyProperties(u, auth);
-    return auth;
+    return ResponseEntity.ok(auth);
   }
 
-  public User registerNewUser(User registerRequest) {
-    User newUser;
+  public ResponseEntity<User> registerNewUser(AuthDTO request) {
+    User user = new User();
+    BeanUtils.copyProperties(request, user);
 
     // Aseguramos que tenga un rol, por defecto es cliente
-    if (registerRequest.getRol() == null)
-      registerRequest.setRol(UserRol.CLIENT);
+    if (user.getRol() == null)
+      user.setRol(UserRol.CLIENT);
 
-    switch (registerRequest.getRol()) {
+    switch (user.getRol()) {
       case ADMIN: // Not extracted due to its complexity, it's the same as for the user
         User admin = new User();
-        BeanUtils.copyProperties(registerRequest, admin);
-        newUser = userRepository.save(admin);
+        BeanUtils.copyProperties(user, admin);
+        user = userRepository.save(admin);
         break;
 
       case HOTEL_ADMIN:
-        newUser = managerService.save(registerRequest);
+        user = managerService.save(user);
         break;
 
       case CLIENT: // By default
       default:
-        newUser = clientService.save(registerRequest);
+        user = clientService.save(user);
         break;
     }
-    return newUser;
+    return ResponseEntity.ok(user);
   }
 
-  public User updateUserData(int id, String name, String email) {
-    User user = getUserById(id);
+  public ResponseEntity<User> updateUserData(int id, String name, String email) {
+    User user = assertUserById(id);
     user.setName(name);
     user.setEmail(email);
-    return userRepository.save(user);
+    user = userRepository.save(user);
+    return ResponseEntity.ok(user);
   }
 
-  public User changePassword(int id, String password) {
-    User user = getUserById(id);
+  public ResponseEntity<User> changePassword(int id, String password) {
+    User user = assertUserById(id);
     user.setPassword(password);
-    return userRepository.save(user);
+    user = userRepository.save(user);
+    return ResponseEntity.ok(user);
   }
 
-  public User deleteUserById(int id) {
-    User user = getUserById(id);
-    userRepository.deleteById(id);
-    return user;
+  public ResponseEntity<User> deleteUserById(int id) {
+    User user = assertUserById(id);
+    switch (user.getRol()) {
+      case CLIENT:
+        clientService.deleteById(id);
+        break;
+      case HOTEL_ADMIN:
+        managerService.deleteById(id);
+        break;
+      case ADMIN:
+      default:
+        userRepository.deleteById(id);
+        break;
+    }
+    return ResponseEntity.ok(user);
   }
 }
diff --git a/java/services/users/src/main/java/com/uva/api/utils/JwtUtil.java b/java/services/users/src/main/java/com/uva/api/utils/JwtUtil.java
deleted file mode 100644
index e1d665c2c2332def70988441255a3ee20bf29c5f..0000000000000000000000000000000000000000
--- a/java/services/users/src/main/java/com/uva/api/utils/JwtUtil.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.uva.api.utils;
-
-import java.util.Date;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.algorithms.Algorithm;
-import com.uva.api.models.UserRol;
-
-@Component
-public class JwtUtil {
-
-  @Value("${security.jwt.secret-key}")
-  private String secretKey;
-
-  @Value("${security.jwt.kid}")
-  private String kid;
-
-  @Value("${security.jwt.expiration-time}")
-  private long jwtExpiration;
-
-  public long getExpirationTime() {
-    return jwtExpiration;
-  }
-
-  public String generateToken(String name, String email, UserRol rol) {
-    Algorithm algorithm = Algorithm.HMAC256(secretKey);
-    return JWT
-        .create()
-        .withKeyId(kid)
-        .withClaim("name", name)
-        .withClaim("email", email)
-        .withClaim("rol", rol.toString())
-        .withIssuedAt(new Date())
-        .withExpiresAt(new Date(System.currentTimeMillis() + jwtExpiration * 1000))
-        .sign(algorithm);
-  }
-
-  // TODO estaría guapo recuperar métodos de validación para el token de petición
-  // para este servicio
-}
diff --git a/java/services/users/src/main/resources/application.properties b/java/services/users/src/main/resources/application.properties
index 3d3c5062f7694a2d5cfda9e7f09371cbee1358bf..6ad30a8252d53371d2accfd475e783772d1ea2ca 100644
--- a/java/services/users/src/main/resources/application.properties
+++ b/java/services/users/src/main/resources/application.properties
@@ -7,7 +7,6 @@ spring.datasource.username=user
 spring.datasource.password=password
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
-spring.neo4j.security.hostname-verification-enabled=false
 spring.security.user.name=user
 spring.security.user.password=password
 
@@ -16,4 +15,6 @@ security.jwt.secret-key=MiClaveDeSeguridadMuyLargaParaQueNoFalleSpringBoot
 security.jwt.expiration-time=3600000 
 security.jwt.kid=cYz3kNRLAirxVhHXQ5rh5xKrOwHwZVui
 
-external.services.bookings.url=localhost:8401/bookings
\ No newline at end of file
+services.internal.token.url=http://localhost:8101/token/
+services.external.hotels.url=http://localhost:8301/hotels
+services.external.bookings.url=http://localhost:8401/bookings
\ No newline at end of file
diff --git a/poblate/mocks/bookings.json b/poblate/mocks/bookings.json
new file mode 100644
index 0000000000000000000000000000000000000000..bf93e638b17471bc9585c37e0689f6808da03285
--- /dev/null
+++ b/poblate/mocks/bookings.json
@@ -0,0 +1,16 @@
+[
+	{
+		"clientId": 1,
+		"hotelId": 1,
+		"roomId": 2,
+		"startDate": "2024-10-20",
+		"endDate": "2024-10-25"
+	},
+	{
+		"clientId": 3,
+		"hotelId": 2,
+		"roomId": 3,
+		"startDate": "2025-02-22",
+		"endDate": "2025-02-27"
+	}
+]
diff --git a/poblate/mocks/hotels.json b/poblate/mocks/hotels.json
new file mode 100644
index 0000000000000000000000000000000000000000..4331cfea0d6964414b2b702b1cfafeb90a133821
--- /dev/null
+++ b/poblate/mocks/hotels.json
@@ -0,0 +1,48 @@
+[
+	{
+		"name": "Ocean View Hotel",
+		"address": {
+			"streetKind": "Avenida",
+			"streetName": "Marítima",
+			"number": 123,
+			"postCode": "45678",
+			"otherInfo": "Frente al mar"
+		},
+		"managerId": 2,
+		"rooms": [
+			{
+				"roomNumber": "101",
+				"type": "SINGLE",
+				"available": true
+			},
+			{
+				"roomNumber": "102",
+				"type": "DOUBLE",
+				"available": false
+			}
+		]
+	},
+	{
+		"name": "Mountain Retreat",
+		"address": {
+			"streetKind": "Calle",
+			"streetName": "Bosque",
+			"number": 42,
+			"postCode": "98765",
+			"otherInfo": "Cerca del parque nacional"
+		},
+		"managerId": 2,
+		"rooms": [
+			{
+				"roomNumber": "201",
+				"type": "DOUBLE",
+				"available": true
+			},
+			{
+				"roomNumber": "202",
+				"type": "SUITE",
+				"available": true
+			}
+		]
+	}
+]
diff --git a/poblate/mocks/users.json b/poblate/mocks/users.json
new file mode 100644
index 0000000000000000000000000000000000000000..72cd088b876a8b8d5a4adc4e588f01bdf61c3995
--- /dev/null
+++ b/poblate/mocks/users.json
@@ -0,0 +1,20 @@
+[
+	{
+		"name": "John Doe",
+		"email": "john.doe@example.com",
+		"password": "securePassword123",
+		"rol": "CLIENT"
+	},
+	{
+		"name": "Jane Smith",
+		"email": "jane.smith@example.com",
+		"password": "securePassword456",
+		"rol": "HOTEL_ADMIN"
+	},
+	{
+		"name": "Alice Johnson",
+		"email": "alice.johnson@example.com",
+		"password": "securePassword789",
+		"rol": "CLIENT"
+	}
+]