diff --git a/.env b/.env
new file mode 100644
index 0000000000000000000000000000000000000000..7382c152961f175a2eda068dcd828f281fdc3af5
--- /dev/null
+++ b/.env
@@ -0,0 +1,5 @@
+DB_HOST=database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com
+DB_PORT=3306
+DB_USER=admin
+DB_PASSWORD=Test#321
+DB_DATABASE=cycle_connect
\ No newline at end of file
diff --git a/admins_service/main.py b/admins_service/main.py
index a9295967746aca42cd9230234a979f24e7d48b68..5c8ad8ec7c470458d1257c2964d41f79d121343b 100644
--- a/admins_service/main.py
+++ b/admins_service/main.py
@@ -5,6 +5,8 @@ import sqlite3
 import mysql.connector   
 from pathlib import Path
 from typing import Optional, Tuple, List
+from dotenv import load_dotenv
+import os
 
 app = FastAPI()
 
@@ -45,16 +47,20 @@ app.add_middleware(
 #     database='your_database'
 # )
 
+
+
+load_dotenv()  # Take environment variables from .env.
+
 db_connection = mysql.connector.connect(
-    host='database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com',  # or '127.0.0.1' for IPv4 loopback
-    port='3306',  # Specify the port number here
-    user='admin',
-    password='Test#321',
-    database='cycle_connect'
+    host=os.getenv('DB_HOST'),
+    port=os.getenv('DB_PORT'),
+    user=os.getenv('DB_USER'),
+    password=os.getenv('DB_PASSWORD'),
+    database=os.getenv('DB_DATABASE')
 )
-
 cursor = db_connection.cursor()
 
+
 # # Create the Admins table if it doesn't exist
 # cursor.execute('''
 #     CREATE TABLE IF NOT EXISTS Admins (
diff --git a/batchjob.py b/batchjob.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/bikes_service/main.py b/bikes_service/main.py
index 8887c9d3a6f4ef56f52eb3ffaea8a425dcda6743..f9b6ec31cd843be0da07d9689819fb65c046e46c 100644
--- a/bikes_service/main.py
+++ b/bikes_service/main.py
@@ -6,7 +6,9 @@ from typing import List
 import sqlite3
 from pathlib import Path
 from typing import Optional
-import mysql.connector      
+import mysql.connector 
+from dotenv import load_dotenv
+import os     
 
 app = FastAPI()
 
@@ -34,16 +36,19 @@ app.add_middleware(
 #     database='your_database'
 # )
 
+load_dotenv()  # Take environment variables from .env.
+
 db_connection = mysql.connector.connect(
-    host='database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com',  # or '127.0.0.1' for IPv4 loopback
-    port='3306',  # Specify the port number here
-    user='admin',
-    password='Test#321',
-    database='cycle_connect'
+    host=os.getenv('DB_HOST'),
+    port=os.getenv('DB_PORT'),
+    user=os.getenv('DB_USER'),
+    password=os.getenv('DB_PASSWORD'),
+    database=os.getenv('DB_DATABASE')
 )
 cursor = db_connection.cursor()
 
 
+
 # Bike model
 class Bike(BaseModel):
     model: str
@@ -140,11 +145,14 @@ async def read_available_bikes():
 
 @app.get("/bikes/{bike_id}", response_model=Bike)
 async def read_bike(bike_id: int):
-    cursor.execute('SELECT * FROM Bikes WHERE bike_id = ?', (bike_id,))
+    cursor.execute('SELECT * FROM Bikes WHERE bike_id = %s', (bike_id,))
     bike = cursor.fetchone()
     if bike is None:
         raise HTTPException(status_code=404, detail="Bike not found")
     
+    # Format the last_maintenance_date from datetime.date to string
+    last_maintenance_date_formatted = bike[6].strftime('%Y-%m-%d') if bike[6] else None
+    
     # Create a Bike object from the fetched data
     bike_obj = Bike(
         model=bike[1],
@@ -152,7 +160,7 @@ async def read_bike(bike_id: int):
         current_location=bike[3],
         bike_condition=bike[4],
         price_per_hour=bike[5],
-        last_maintenance_date=bike[6],
+        last_maintenance_date=last_maintenance_date_formatted,
         maintenance_history=bike[7]
     )
     
diff --git a/booking_service/main.py b/booking_service/main.py
index 1a1f0b1c9d86471d9c9d948f54dc6aedb6a38554..75700e5f06d6d39483caaf6cf0b1360198cf615e 100644
--- a/booking_service/main.py
+++ b/booking_service/main.py
@@ -8,6 +8,10 @@ from fastapi.middleware.cors import CORSMiddleware # type: ignore
 import sqlite3
 from pathlib import Path
 from typing import List
+import mysql.connector 
+from dotenv import load_dotenv
+import os
+
 
 app = FastAPI()
 
@@ -20,10 +24,18 @@ app.add_middleware(
     allow_headers=["*"],
 )
 
-parent_directory = Path(__file__).resolve().parent.parent
-db_file_path = parent_directory / "my_ride.db"
-conn = sqlite3.connect(db_file_path, check_same_thread=False)
-cursor = conn.cursor()
+
+load_dotenv()  # Take environment variables from .env.
+
+db_connection = mysql.connector.connect(
+    host=os.getenv('DB_HOST'),
+    port=os.getenv('DB_PORT'),
+    user=os.getenv('DB_USER'),
+    password=os.getenv('DB_PASSWORD'),
+    database=os.getenv('DB_DATABASE')
+)
+cursor = db_connection.cursor()
+
 
 class Booking(BaseModel):
     user_id: int
@@ -73,7 +85,7 @@ async def get_all_bookings():
 @app.get("/bookings/{booking_id}", response_model=BookingResponse)
 async def get_booking(booking_id: int):
     # Execute the SQL query to fetch booking details by booking_id
-    cursor.execute("SELECT booking_id, user_id, bike_id, location, blocked_amount, payment_state, start_time, end_time, lock_code FROM Bookings WHERE booking_id = ?", (booking_id,))
+    cursor.execute("SELECT booking_id, user_id, bike_id, location, blocked_amount, payment_state, start_time, end_time, lock_code FROM Bookings WHERE booking_id = %s", (booking_id,))
     booking = cursor.fetchone()
 
     # If no booking is found, raise a 404 error
@@ -98,7 +110,7 @@ async def book_bike(booking: Booking):
     # Check for existing active booking for the user_id or bike_id
     cursor.execute("""
         SELECT 1 FROM Bookings
-        WHERE (user_id = ? OR bike_id = ?) AND payment_state = 'Booked'
+        WHERE (user_id = %s OR bike_id = %s) AND payment_state = 'Booked'
     """, (booking.user_id, booking.bike_id))
     existing_booking = cursor.fetchone()
 
@@ -106,20 +118,20 @@ async def book_bike(booking: Booking):
         raise HTTPException(status_code=400, detail="Already Booked")
 
     # Fetch user details
-    cursor.execute("SELECT wallet_balance FROM Users WHERE user_id = ?", (booking.user_id,))
+    cursor.execute("SELECT wallet_balance FROM Users WHERE user_id = %s", (booking.user_id,))
     user_details = cursor.fetchone()
     if not user_details:
         raise HTTPException(status_code=404, detail="User not found.")
     wallet_balance = user_details[0]
 
     # Fetch bike details and validate the location
-    cursor.execute("SELECT location, price_per_hour FROM Bikes WHERE bike_id = ?", (booking.bike_id,))
+    cursor.execute("SELECT current_location, price_per_hour FROM Bikes WHERE bike_id = %s", (booking.bike_id,))
     bike_details = cursor.fetchone()
     if not bike_details:
         raise HTTPException(status_code=404, detail="Bike not found.")
     db_location, price_per_hour = bike_details
 
-    if booking.location != db_location:
+    if booking.current_location != db_location:
         raise HTTPException(status_code=400, detail="Bike not available at the specified location.")
 
     # Calculate the amount to be blocked on the user's wallet
@@ -137,16 +149,16 @@ async def book_bike(booking: Booking):
     start_time = datetime.now()
 
     # Update bike status and user's wallet balance
-    cursor.execute("UPDATE Bikes SET status = 'booked' WHERE bike_id = ?", (booking.bike_id,))
-    cursor.execute("UPDATE Users SET wallet_balance = ? WHERE user_id = ?", (new_wallet_balance, booking.user_id))
+    cursor.execute("UPDATE Bikes SET status = 'booked' WHERE bike_id = %s", (booking.bike_id,))
+    cursor.execute("UPDATE Users SET wallet_balance = %s WHERE user_id = %s", (new_wallet_balance, booking.user_id))
 
     # Insert a new booking record with lock code
     cursor.execute("""
         INSERT INTO Bookings (user_id, bike_id, location, blocked_amount, payment_state, start_time, lock_code)
-        VALUES (?, ?, ?, ?, 'Booked', ?, ?)
+        VALUES (%s, %s, %s, %s, 'Booked', %s, %s)
     """, (booking.user_id, booking.bike_id, booking.location, blocked_amount, start_time, lock_code))
 
-    conn.commit()
+    db_connection.commit()
 
     return {
         "user_id": booking.user_id,
@@ -162,6 +174,16 @@ async def book_bike(booking: Booking):
 
 @app.put("/bookings/")
 async def update_booking(update: UpdateBooking):
+    # Establish a database connection
+    db_connection = mysql.connector.connect(
+        host='database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com',
+        port='3306',
+        user='admin',
+        password='Test#321',
+        database='cycle_connect'
+    )
+    cursor = db_connection.cursor()
+
     # Check if the booking with provided booking_id, user_id, and bike_id exists
     cursor.execute("""
         SELECT 
@@ -171,7 +193,7 @@ async def update_booking(update: UpdateBooking):
             JOIN Bikes Bi ON B.bike_id = Bi.bike_id
             JOIN Users U ON B.user_id = U.user_id
         WHERE 
-            B.booking_id = ? AND B.user_id = ? AND B.bike_id = ?
+            B.booking_id = %s AND B.user_id = %s AND B.bike_id = %s
     """, (update.booking_id, update.user_id, update.bike_id))
     booking = cursor.fetchone()
 
@@ -181,9 +203,13 @@ async def update_booking(update: UpdateBooking):
     # Unpack fetched details
     start_time, blocked_amount, price_per_hour, current_wallet_balance = booking
 
+    # Handle start_time type appropriately
+    if not isinstance(start_time, datetime):
+        start_time = datetime.fromisoformat(start_time)
+
     # Calculate total runtime in hours
     end_time = datetime.now()
-    total_runtime = (end_time - datetime.fromisoformat(start_time)).total_seconds() / 3600
+    total_runtime = (end_time - start_time).total_seconds() / 3600
 
     # Determine final price based on total runtime
     if total_runtime <= 5:
@@ -195,10 +221,11 @@ async def update_booking(update: UpdateBooking):
     new_wallet_balance = current_wallet_balance + final_price
 
     # Update Booking and Users records
-    cursor.execute("UPDATE Bookings SET end_time = ?, payment_state = 'Ride Completed' WHERE booking_id = ?", (end_time, update.booking_id))
-    cursor.execute("UPDATE Users SET wallet_balance = ? WHERE user_id = ?", (new_wallet_balance, update.user_id))
+    cursor.execute("UPDATE Bookings SET end_time = %s, payment_state = 'Ride Completed' WHERE booking_id = %s", (end_time.strftime('%Y-%m-%d %H:%M:%S'), update.booking_id))
+    cursor.execute("UPDATE Users SET wallet_balance = %s WHERE user_id = %s", (new_wallet_balance, update.user_id))
 
-    conn.commit()
+    db_connection.commit()
+    db_connection.close()
 
     return {
         "message": "Booking updated and charges applied successfully",
diff --git a/rentals_service/main.py b/rentals_service/main.py
index f4224ced693614770e1239396de0792304e71ce6..eca1a8a3e25b4e7951df46c9b5064700ceff3dcf 100644
--- a/rentals_service/main.py
+++ b/rentals_service/main.py
@@ -7,6 +7,9 @@ from pathlib import Path
 from typing import Optional
 from fastapi import HTTPException
 import mysql.connector   
+from decimal import Decimal
+from dotenv import load_dotenv
+import os
 
 app = FastAPI()
 
@@ -19,58 +22,23 @@ app.add_middleware(
     allow_headers=["*"],
 )
 
-# # SQLite connection
-# parent_directory = Path(__file__).resolve().parent.parent
-# db_file_path = parent_directory / "my_ride.db"
-# # print(db_file_path)
-# conn = sqlite3.connect(db_file_path)
-# cursor = conn.cursor()
-
-# db_connection = mysql.connector.connect(
-#     host='database_mysql',  # or '127.0.0.1' for IPv4 loopback
-#     port='3306',  # Specify the port number here
-#     user='root',
-#     password='root_password',
-#     database='your_database'
-# )
+
+load_dotenv()  # Take environment variables from .env.
 
 db_connection = mysql.connector.connect(
-    host='database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com',  # or '127.0.0.1' for IPv4 loopback
-    port='3306',  # Specify the port number here
-    user='admin',
-    password='Test#321',
-    database='cycle_connect'
+    host=os.getenv('DB_HOST'),
+    port=os.getenv('DB_PORT'),
+    user=os.getenv('DB_USER'),
+    password=os.getenv('DB_PASSWORD'),
+    database=os.getenv('DB_DATABASE')
 )
-
 cursor = db_connection.cursor()
 
-# # Create the Rentals table if it doesn't exist
-# cursor.execute('''
-#     CREATE TABLE IF NOT EXISTS Rentals (
-#         rental_id INTEGER PRIMARY KEY,
-#         id INT,
-#         user_id INT,
-#         bike_id INT,
-#         year INT,
-#         hour INT,
-#         season INT,
-#         holiday BOOLEAN,
-#         workingday BOOLEAN,
-#         weather INT,
-#         temp DECIMAL(5, 2),
-#         atemp DECIMAL(5, 2),
-#         humidity DECIMAL(5, 2),
-#         windspeed DECIMAL(5, 2),
-#         count INT,
-#         FOREIGN KEY (user_id) REFERENCES Users(user_id),
-#         FOREIGN KEY (bike_id) REFERENCES Bikes(bike_id)
-#     )
-# ''')
-# conn.commit()
 
 
 # Rental model
 class Rental(BaseModel):
+    booking_id: int  
     user_id: int
     bike_id: int
     year: int
@@ -86,73 +54,15 @@ class Rental(BaseModel):
     count: int
 
 
-# # Routes
-# @app.post("/rentals/", response_model=Rental)
-# async def create_rental(rental: Rental):
-#     cursor.execute('''
-#         INSERT INTO Rentals 
-#         (id, user_id, bike_id, year, hour, season, holiday, workingday, weather, temp, atemp, humidity, windspeed, count) 
-#         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-#     ''', (
-#         rental.id, rental.user_id, rental.bike_id, rental.year, rental.hour,
-#         rental.season, rental.holiday, rental.workingday, rental.weather,
-#         rental.temp, rental.atemp, rental.humidity, rental.windspeed, rental.count
-#     ))
-#     conn.commit()
-#     return rental
-
-
-# @app.post("/rentals/", response_model=Rental)
-# async def create_rental(rental: Rental):
-#     try:
-#         cursor.execute('''
-#             INSERT INTO Rentals 
-#             (id, user_id, bike_id, year, hour, season, holiday, workingday, weather, temp, atemp, humidity, windspeed, count) 
-#             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-#         ''', (
-#             rental.id, rental.user_id, rental.bike_id, rental.year, rental.hour,
-#             rental.season, rental.holiday, rental.workingday, rental.weather,
-#             rental.temp, rental.atemp, rental.humidity, rental.windspeed, rental.count
-#         ))
-#         conn.commit()
-#         return rental
-#     except Exception as e:
-#         # Log the exception
-#         print(f"Error creating rental: {e}")
-#         # Raise an HTTPException with status code 422 and error message
-#         raise HTTPException(status_code=422, detail=str(e))
-
-
-# @app.post("/rentals/", response_model=Rental)
-# async def create_rental(rental: Rental):
-#     try:
-#         cursor.execute('''
-#             INSERT INTO Rentals 
-#             (id, user_id, bike_id, year, hour, season, holiday, workingday, weather, temp, atemp, humidity, windspeed, count) 
-#             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-#         ''', (
-#             rental.id, rental.user_id, rental.bike_id, rental.year, rental.hour,
-#             rental.season, rental.holiday, rental.workingday, rental.weather,
-#             rental.temp, rental.atemp, rental.humidity, rental.windspeed, rental.count
-#         ))
-#         conn.commit()
-#         return rental
-#     except Exception as e:
-#         # Log the exception
-#         print(f"Error creating rental: {e}")
-#         # Raise an HTTPException with status code 422 and error message
-#         raise HTTPException(status_code=422, detail=str(e))
-
-
 @app.post("/rentals/", response_model=Rental)
 async def create_rental(rental: Rental):
     try:
         cursor.execute('''
             INSERT INTO Rentals 
-            (user_id, bike_id, year, hour, season, holiday, workingday, weather, temp, atemp, humidity, windspeed, count) 
-            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
+            (booking_id, user_id, bike_id, year, hour, season, holiday, workingday, weather, temp, atemp, humidity, windspeed, count) 
+            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
         ''', (
-            rental.user_id, rental.bike_id, rental.year, rental.hour,
+            rental.booking_id, rental.user_id, rental.bike_id, rental.year, rental.hour,
             rental.season, rental.holiday, rental.workingday, rental.weather,
             rental.temp, rental.atemp, rental.humidity, rental.windspeed, rental.count
         ))
@@ -160,7 +70,7 @@ async def create_rental(rental: Rental):
         # Get the auto-generated id of the new rental
         rental_id = cursor.lastrowid
         # Return the created rental with the generated id
-        rental.id = rental_id
+        rental.booking_id = rental_id
         return rental
     except Exception as e:
         # Log the exception
@@ -174,26 +84,9 @@ async def create_rental(rental: Rental):
 async def read_rentals():
     cursor.execute('SELECT * FROM Rentals')
     rentals = cursor.fetchall()
-    rental_objects = []
-    # for rental in rentals:
-    #     rental_objects.append(Rental(
-    #         id=rental[0],
-    #         user_id=rental[1],
-    #         bike_id=rental[2],
-    #         year=rental[3],
-    #         hour=rental[4],
-    #         season=rental[5],
-    #         holiday=bool(rental[6]),
-    #         workingday=bool(rental[7]),
-    #         weather=rental[8],
-    #         temp=float(rental[9]),
-    #         atemp=float(rental[10]),
-    #         humidity=float(rental[11]),
-    #         windspeed=float(rental[12]),
-    #         count=int(rental[13])  # Convert to integer
-    #     ))
-    for rental in rentals:
-        rental_objects.append(Rental(
+    rental_objects = [
+        Rental(
+            booking_id=rental[0],
             user_id=rental[1],
             bike_id=rental[2],
             year=rental[3],
@@ -207,30 +100,49 @@ async def read_rentals():
             humidity=float(rental[11]),
             windspeed=float(rental[12]),
             count=rental[13]
-        ))
-    
+        ) for rental in rentals
+    ]
     return rental_objects
 
 
 @app.get("/rentals/{rental_id}", response_model=Rental)
 async def read_rental(rental_id: int):
-    cursor.execute('SELECT * FROM Rentals WHERE rental_id = ?', (rental_id,))
+    cursor.execute('SELECT * FROM Rentals WHERE rental_id = %s', (rental_id,))
     rental = cursor.fetchone()
     if rental is None:
         raise HTTPException(status_code=404, detail="Rental not found")
-    return rental
+
+    # Convert the tuple to a dictionary
+    rental_dict = {
+        'booking_id': rental[0],
+        'user_id': rental[1],
+        'bike_id': rental[2],
+        'year': rental[3],
+        'hour': rental[4],
+        'season': rental[5],
+        'holiday': bool(rental[6]),
+        'workingday': bool(rental[7]),
+        'weather': rental[8],
+        'temp': float(rental[9]),
+        'atemp': float(rental[10]),
+        'humidity': float(rental[11]),
+        'windspeed': float(rental[12]),
+        'count': rental[13]
+    }
+
+    return Rental(**rental_dict)
 
 
 @app.put("/rentals/{rental_id}", response_model=Rental)
 async def update_rental(rental_id: int, rental: Rental):
     cursor.execute('''
         UPDATE Rentals 
-        SET id = ?, user_id = ?, bike_id = ?, year = ?, hour = ?, season = ?, 
-        holiday = ?, workingday = ?, weather = ?, temp = ?, atemp = ?, 
-        humidity = ?, windspeed = ?, count = ?
-        WHERE rental_id = ?
+        SET booking_id = %s, user_id = %s, bike_id = %s, year = %s, hour = %s, season = %s, 
+        holiday = %s, workingday = %s, weather = %s, temp = %s, atemp = %s, 
+        humidity = %s, windspeed = %s, count = %s
+        WHERE rental_id = %s
     ''', (
-        rental.id, rental.user_id, rental.bike_id, rental.year, rental.hour,
+        rental.booking_id, rental.user_id, rental.bike_id, rental.year, rental.hour,
         rental.season, rental.holiday, rental.workingday, rental.weather,
         rental.temp, rental.atemp, rental.humidity, rental.windspeed,
         rental.count, rental_id
diff --git a/requirements.txt b/requirements.txt
index 6c5d0fd629eb8d43f287e646dcef2a1d9fb7a8f4..a7bfeb9154d409c0ff24328460c9815f66bd274a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -32,3 +32,6 @@ uvicorn==0.29.0
 uvloop==0.19.0
 watchfiles==0.21.0
 websockets==12.0
+mysql-connector-python
+apscheduler
+python-dotenv
diff --git a/reviews_service/main.py b/reviews_service/main.py
index 17522db3609be1940d968607b834572d1b5fd51f..bf5ff0b7302748a8cbf785b680f0b8aaa840fff0 100644
--- a/reviews_service/main.py
+++ b/reviews_service/main.py
@@ -5,7 +5,9 @@ from typing import List
 import sqlite3
 from pathlib import Path
 from typing import Optional
-import mysql.connector  
+import mysql.connector
+from dotenv import load_dotenv
+import os  
 
 app = FastAPI()
 # Allow requests from all origins
@@ -18,47 +20,20 @@ app.add_middleware(
 )
 
 
-# # SQLite connection
-# parent_directory = Path(__file__).resolve().parent.parent
-# db_file_path = parent_directory / "my_ride.db"
-# # print(db_file_path)
-# conn = sqlite3.connect(db_file_path)
-# cursor = conn.cursor()
-
-# # Create the Reviews table if it doesn't exist
-# cursor.execute('''
-#     CREATE TABLE IF NOT EXISTS Reviews (
-#         review_id INTEGER PRIMARY KEY AUTOINCREMENT,
-#         user_id INT,
-#         bike_id INT,
-#         rating INT,
-#         comment TEXT,
-#         review_date DATETIME,
-#         FOREIGN KEY (user_id) REFERENCES Users(user_id),
-#         FOREIGN KEY (bike_id) REFERENCES Bikes(bike_id)
-#     )
-# ''')
-# conn.commit()
-
-# db_connection = mysql.connector.connect(
-#     host='database_mysql',  # or '127.0.0.1' for IPv4 loopback
-#     port='3306',  # Specify the port number here
-#     user='root',
-#     password='root_password',
-#     database='your_database'
-# )
+
+load_dotenv()  # Take environment variables from .env.
 
 db_connection = mysql.connector.connect(
-    host='database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com',  # or '127.0.0.1' for IPv4 loopback
-    port='3306',  # Specify the port number here
-    user='admin',
-    password='Test#321',
-    database='cycle_connect'
+    host=os.getenv('DB_HOST'),
+    port=os.getenv('DB_PORT'),
+    user=os.getenv('DB_USER'),
+    password=os.getenv('DB_PASSWORD'),
+    database=os.getenv('DB_DATABASE')
 )
-
 cursor = db_connection.cursor()
 
 
+
 # Review model
 class Review(BaseModel):
     user_id: int
@@ -67,6 +42,21 @@ class Review(BaseModel):
     comment: str
     review_date: str
 
+class GetReview(BaseModel):
+    review_id:int
+    user_id: int
+    bike_id: int
+    rating: int
+    comment: str
+    review_date: str
+
+class UpdateReview(BaseModel):
+    user_id: Optional[int] = None
+    bike_id: Optional[int] = None
+    rating: Optional[int] = None
+    comment: Optional[str] = None
+    review_date: Optional[str] = None
+
 
 # Routes
 @app.post("/reviews/", response_model=Review)
@@ -79,7 +69,8 @@ async def create_review(review: Review):
         review.user_id, review.bike_id, review.rating, review.comment, review.review_date
     ))
     db_connection.commit()
-    return review
+    review_id = cursor.lastrowid  # Get the last inserted id
+    return {**review.dict(), "review_id": review_id}
 
 
 @app.get("/reviews/", response_model=List[Review])
@@ -99,27 +90,60 @@ async def read_reviews():
     return review_objects
 
 
-@app.get("/reviews/{review_id}", response_model=Review)
+@app.get("/reviews/{review_id}", response_model=GetReview)
 async def read_review(review_id: int):
-    cursor.execute('SELECT * FROM Reviews WHERE review_id = %s', (review_id,))
+    # Execute the query to fetch the review
+    cursor.execute('SELECT review_id, user_id, bike_id, rating, comment, review_date FROM Reviews WHERE review_id = %s', (review_id,))
     review = cursor.fetchone()
     if review is None:
         raise HTTPException(status_code=404, detail="Review not found")
-    return review
+
+    # Check if review_date is not None and format it as string
+    review_date_formatted = review[5].strftime('%Y-%m-%d %H:%M:%S') if review[5] else None
+
+    # Return the formatted review data using the GetReview model
+    return GetReview(
+        review_id=review[0],
+        user_id=review[1],
+        bike_id=review[2],
+        rating=review[3],
+        comment=review[4],
+        review_date=review_date_formatted
+    )
 
 
 @app.put("/reviews/{review_id}", response_model=Review)
-async def update_review(review_id: int, review: Review):
-    cursor.execute('''
-        UPDATE Reviews 
-        SET user_id = %s, bike_id = %s, rating = %s, comment = %s, review_date = %s
-        WHERE review_id = %s
-    ''', (
-        review.user_id, review.bike_id, review.rating, review.comment,
-        review.review_date, review_id
-    ))
+async def update_review(review_id: int, review_update: UpdateReview):
+    updates = []
+    values = []
+    for field, value in review_update.dict(exclude_none=True).items():
+        updates.append(f"{field} = %s")
+        values.append(value)
+
+    if not updates:
+        raise HTTPException(status_code=400, detail="No fields provided for update")
+
+    update_stmt = f"UPDATE Reviews SET {', '.join(updates)} WHERE review_id = %s"
+    values.append(review_id)
+    cursor.execute(update_stmt, tuple(values))
     db_connection.commit()
-    return review
+
+    # Fetch the updated review data
+    cursor.execute('SELECT review_id, user_id, bike_id, rating, comment, review_date FROM Reviews WHERE review_id = %s', (review_id,))
+    updated_review = cursor.fetchone()
+    if updated_review:
+        review_dict = {
+            'review_id': updated_review[0],
+            'user_id': updated_review[1],
+            'bike_id': updated_review[2],
+            'rating': updated_review[3],
+            'comment': updated_review[4],
+            'review_date': updated_review[5].strftime('%Y-%m-%d %H:%M:%S') if updated_review[5] else None
+        }
+        return Review(**review_dict)
+    else:
+        raise HTTPException(status_code=404, detail="Error updating review.")
+
 
 
 @app.delete("/reviews/{review_id}")
diff --git a/users_service/main.py b/users_service/main.py
index 7824bf9546283f8b89e65fe09ebc398d6bbff817..956c480b5262380b3ee1ec93112373a9d6cf1880 100644
--- a/users_service/main.py
+++ b/users_service/main.py
@@ -6,6 +6,10 @@ import sqlite3
 import mysql.connector   
 from pathlib import Path
 from typing import Optional
+from datetime import datetime
+from dotenv import load_dotenv
+import os
+
 
 app = FastAPI()
 
@@ -18,45 +22,18 @@ app.add_middleware(
     allow_headers=["*"],
 )
 
-# # SQLite connection
-# parent_directory = Path(__file__).resolve().parent.parent
-# db_file_path = parent_directory / "my_ride.db"
-# # print(db_file_path)
-# conn = sqlite3.connect(db_file_path)
-
-# cursor = conn.cursor()
-
-# # Create the Users table if it doesn't exist
-# cursor.execute('''
-#     CREATE TABLE IF NOT EXISTS Users (
-#         user_id INTEGER PRIMARY KEY,
-#         username TEXT,
-#         password TEXT,
-#         email TEXT,
-#         phone_number TEXT,
-#         credit_card_info TEXT,
-#         registration_date DATETIME,
-#         last_login DATETIME
-#     )
-# ''')
-# conn.commit()
-
-# db_connection = mysql.connector.connect(
-#     host='database_mysql',  # or '127.0.0.1' for IPv4 loopback
-#     port='3306',  # Specify the port number here
-#     user='root',
-#     password='root_password',
-#     database='your_database'
-# )
+
+
+
+load_dotenv()  # Take environment variables from .env.
 
 db_connection = mysql.connector.connect(
-    host='database-1.cz0ucmk42cu5.us-east-1.rds.amazonaws.com',  # or '127.0.0.1' for IPv4 loopback
-    port='3306',  # Specify the port number here
-    user='admin',
-    password='Test#321',
-    database='cycle_connect'
+    host=os.getenv('DB_HOST'),
+    port=os.getenv('DB_PORT'),
+    user=os.getenv('DB_USER'),
+    password=os.getenv('DB_PASSWORD'),
+    database=os.getenv('DB_DATABASE')
 )
-
 cursor = db_connection.cursor()
 
 class User(BaseModel):
@@ -67,6 +44,16 @@ class User(BaseModel):
     credit_card_info: Optional[str] = None
     registration_date: str
     last_login: Optional[str] = None
+    wallet_balance:Optional[float] = None
+class UpdateUserModel(BaseModel):
+    username: Optional[str] = None
+    password: Optional[str] = None
+    email: Optional[str] = None
+    phone_number: Optional[str] = None
+    credit_card_info: Optional[str] = None
+    registration_date: Optional[str] = None
+    last_login: Optional[str] = None
+    wallet_balance:Optional[float] = None
 
 
 class UserResponse(BaseModel):
@@ -75,12 +62,14 @@ class UserResponse(BaseModel):
     email: str
     phone_number: str
     registration_date: str
+    last_login: Optional[str] = None 
+    wallet_balance:float
 
 
 # Modify the read_users() function to return a list of UserResponse objects
 @app.get("/users/", response_model=List[UserResponse])
 async def read_users():
-    cursor.execute('SELECT user_id, username, email, phone_number, registration_date FROM Users')
+    cursor.execute('SELECT user_id, username, email, phone_number, registration_date, wallet_balance FROM Users')
     print("got record")
     users = cursor.fetchall()
     user_objects = []
@@ -90,12 +79,16 @@ async def read_users():
             username=user[1],
             email=user[2],
             phone_number=user[3],
-            registration_date=user[4].strftime('%Y-%m-%d %H:%M:%S') 
+            registration_date=user[4].strftime('%Y-%m-%d %H:%M:%S') ,
+            wallet_balance=user[5]
         )
         user_objects.append(user_obj)
     return user_objects
 
 
+
+
+
 # Routes
 @app.post("/users/", response_model=User)
 async def create_user(user: User):
@@ -114,7 +107,7 @@ async def create_user(user: User):
         cursor.execute('''
             INSERT INTO Users 
             (username, password, email, phone_number, registration_date, last_login) 
-            VALUES (%s, %s, %s, %s, %s)
+            VALUES (%s, %s, %s, %s, %s, %s)
         ''', (
             user.username, user.password, user.email, user.phone_number,
             user.registration_date, user.last_login
@@ -123,7 +116,7 @@ async def create_user(user: User):
         cursor.execute('''
             INSERT INTO Users 
             (username, password, email, phone_number, credit_card_info, registration_date) 
-            VALUES (%s, %s, %s, %s, %s)
+            VALUES (%s, %s, %s, %s, %s, %s)
         ''', (
             user.username, user.password, user.email, user.phone_number,
             user.credit_card_info, user.registration_date
@@ -132,7 +125,7 @@ async def create_user(user: User):
         cursor.execute('''
             INSERT INTO Users 
             (username, password, email, phone_number, credit_card_info, registration_date, last_login) 
-            VALUES (%s, %s, %s, %s, %s)
+            VALUES (%s, %s, %s, %s, %s, %s, %s)
         ''', (
             user.username, user.password, user.email, user.phone_number,
             user.credit_card_info, user.registration_date, user.last_login
@@ -142,28 +135,71 @@ async def create_user(user: User):
 
 
 
-@app.get("/users/{user_id}", response_model=User)
-async def read_user(user_id: int):
-    cursor.execute('SELECT * FROM Users WHERE user_id = ?', (user_id,))
+
+
+@app.get("/users/{username}", response_model=UserResponse)
+async def read_user_by_username(username: str):
+    cursor.execute('SELECT user_id, username, email, phone_number, registration_date, last_login, wallet_balance FROM Users WHERE username = %s', (username,))
     user = cursor.fetchone()
     if user is None:
         raise HTTPException(status_code=404, detail="User not found")
-    return user
-
+    
+    # Format datetime fields as strings
+    registration_date = user[4].strftime('%Y-%m-%d %H:%M:%S') if user[4] else None
+    last_login = user[5].strftime('%Y-%m-%d %H:%M:%S') if user[5] else None
+
+    return UserResponse(
+        user_id=user[0],
+        username=user[1],
+        email=user[2],
+        phone_number=user[3],
+        registration_date=registration_date,
+        last_login=last_login,
+        wallet_balance=user[6]
+    )
+
+
+@app.put("/users/{user_id}", response_model=UserResponse)
+async def update_user(user_id: int, update_data: UpdateUserModel):
+    # Fetch the existing user data first to compare what needs to be updated
+    cursor.execute('SELECT * FROM Users WHERE user_id = %s', (user_id,))
+    existing_user = cursor.fetchone()
+    if not existing_user:
+        raise HTTPException(status_code=404, detail="User not found")
 
-@app.put("/users/{user_id}", response_model=User)
-async def update_user(user_id: int, user: User):
-    cursor.execute('''
-        UPDATE Users 
-        SET username = %s, password = %s, email = %s, phone_number = %s, 
-        credit_card_info = %s, registration_date = %s, last_login = %s
-        WHERE user_id = %s
-    ''', (
-        user.username, user.password, user.email, user.phone_number,
-        user.credit_card_info, user.registration_date, user.last_login, user_id
-    ))
+    # Prepare the SQL query to update only provided fields
+    updates = []
+    params = []
+    for field, value in update_data.dict(exclude_none=True).items():
+        if value is not None:
+            updates.append(f"{field} = %s")
+            params.append(value)
+    
+    if not updates:
+        raise HTTPException(status_code=400, detail="No valid fields provided for update")
+
+    # Execute the update query
+    params.append(user_id)
+    update_stmt = f"UPDATE Users SET {', '.join(updates)} WHERE user_id = %s"
+    cursor.execute(update_stmt, params)
     db_connection.commit()
-    return user
+
+    # Fetch and return the updated user data
+    cursor.execute('SELECT user_id, username, email, phone_number, registration_date, last_login, wallet_balance FROM Users WHERE user_id = %s', (user_id,))
+    updated_user = cursor.fetchone()
+    if updated_user:
+        return UserResponse(
+            user_id=updated_user[0],
+            username=updated_user[1],
+            email=updated_user[2],
+            phone_number=updated_user[3],
+            registration_date=updated_user[4].strftime('%Y-%m-%d %H:%M:%S') if updated_user[4] else None,
+            last_login=updated_user[5].strftime('%Y-%m-%d %H:%M:%S') if updated_user[5] else None,
+            wallet_balance=updated_user[6]
+        )
+    else:
+        raise HTTPException(status_code=404, detail="Error updating user.")
+
 
 
 @app.delete("/users/{user_id}")