Video : https://www.youtube.com/watch?v=u0fEbt3YS5w
Note for the TA Because of the short time of the video, we didn't have the time to properly show all the features our app can do, so please make sure to run the app, and explore all the routes. For Example, A user can book multiple offerings if and only if they are not at the same time as one of their previous bookings, etc.
To set up and start the application, follow these steps:
- Clone the repository:
git clone https://github.com/antoinemansour7/SOEN342.git cd SOEN342 - Set up a virtual environment (recommended):
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
- Install dependencies:
pip install -r requirements.txt
- Set up the database:
flask db init flask db migrate flask db upgrade
- Run the application:
flask run
The app will be available at http://127.0.0.1:5000.
- Login credentials : Admin username: admin Admin password: adminpassword
Concurrency Management with Locks
To ensure data consistency and thread safety, we implemented reader-writer locks using Python's threading.Lock. Critical operations, such as creating offerings, creating locations, and attending offerings, are protected with locks to prevent race conditions.
Writer Locks: Used in routes like create_offering and create_location to ensure only one Admin can modify shared resources (e.g., the database and in-memory catalogs) at a time. Reader and Writer Locks: Used in attend_offering to allow multiple clients to read offering details simultaneously, while ensuring only one client can update booking details at a time. This approach ensures consistency and prevents conflicting updates during concurrent user actions.
System Sequence Diagram of Administrator:
System Sequence Diagram of Instructors:
System Sequence Diagram of Clients:
Operation: login(username, password)
Cross reference: Use Case Process Offerings, Use Case Process Bookings
-
Preconditions:
- The credentials must exist in the system.
-
Postconditions:
- If valid, the
setRolemethod sets the role of the user as either anadmin,instructororclient. - If valid, the user with the role is authenticated into the system
- If invalid, an error message is shown.
- If valid, the
Operation: create_location(city, address, location)
Cross reference: Use Case Process Offerings
-
Preconditions:
- The
Administratoris logged in. - The
locationdetails must include valid detals.
- The
-
Postconditions:
- If the
locationis unique (checked bycheckLocationUniqueness()) with valid details, the system creates the new offering. - If the
locationis not unique or has invalid details, the system returns an error message.
- If the
Operation: create_offering(lessonType, offeringType, startTime, endTime, date, maxCapacity)
Cross reference: Use Case Process Offerings
-
Preconditions:
- The
Administratoris logged in. - The
offeringdetails must include valid detals.
- The
-
Postconditions:
- If the
offeringis unique (checked bycheckOfferingUniqueness) with valid details, the system creates the new offering. - If the
offeringis not unique or has invalid details, the system returns an error message.
- If the
Operation: delete_offering(offering_id)
Cross reference: Use Case Process Offerings
-
Preconditions:
- The
Administratoris logged in. - The
offeringmust exist in the catalog of offerings.
- The
-
Postconditions:
- The
offeringis deleted. - The
offeringis removed from the list of claimed offerings of the assigned instructor. - The
offeringis removed from the list of bookings of the participating clients.
- The
Operation: remove_attendee(offering_id, user_id)
Cross reference: Use Case Process Offerings, Use Case Process Bookings
-
Preconditions:
- The
Administratoris logged in. - The
clientmust exist in theoffering's list of attendees.
- The
-
Postconditions:
- The
clientis removed from the list of attendees of theoffering - The
offeringis removed from the list of bookings of the participating clients. - The
offeringis displayed with a capacity of 1 more than before.
- The
Operation: delete_user(user_id, user_type)
Cross reference: Use Case Process Offerings
-
Preconditions:
- The
Administratoris logged in. - The
user_idof the selecteduser_typeexists in the system
- The
-
Postconditions:
- The
user's profile is deleted. - If
user_typewas instructor, all claimedofferingof the instructor is no more public (moved to unassignedOfferings to be claimed) - If
user_typewas client, all attendingofferingfrombookingof the client is removed and displayed with a capacity of 1 more than before.
- The
Operation: diaplayUnassignedOfferings()
Cross reference: Use Case Process Offerings
-
Preconditions:
- The
adminorInstructoris authenticated and logged in.
- The
-
Postconditions:
- If there exists, the system returns a list of all available
offerings(those that have not been claimed by an instructor). - If there are no unassigned
offerings, an empty page is shown.
- If there exists, the system returns a list of all available
Operation: claim_offering(offering_id)
Cross reference: Use Case Process Offerings
-
Preconditions:
- The
Instructoris authenticated and logged in. - The
offeringmust be available (found bydiaplayUnassignedOfferings()). - The
offeringschedule must not conflict with another claimed offering's schedule of the instructor. - The
offeringcity and lessonType must match theInstructorcity and speciality that they are available to work in.
- The
-
Postconditions:
- The selected
offeringis now associated with theinstructor. - The
offeringis removed from the list of unassigned offerings. - The
offeringis public and anyone can see it or attend it.
- The selected
Operation: dispplayOfferings()
Cross reference: Use Case Process Offerings, Process Bookings
-
Preconditions:
- An
offeringhas been claimed by an instructor.
- An
-
Postconditions:
- The list of
offeringsclaimed by instructors are displayed to the user (guest or registered).
- The list of
Operation: attend_offering(offering_id)
Cross reference: Use Case Process Bookings
-
Preconditions:
- The
Clientis authenticated and logged in. - The
Clienthas selected the person to book the offering for (themselves or a child that they will accompany) - The
offeringmust have available capacity. - The
offering's startTime and endTime must not conflict with another scheduled booking of theClient.
- The
-
Postconditions:
- The selected
offeringis now booked by theClient. - The
offeringis displayed with a capacity of 1 less than before. - The
offeringand its details are now available underbookingsof theClient.
- The selected
Operation: view_your_bookings()
Cross reference: Use Case Process Bookings
-
Preconditions:
- The
Clientis authenticated and logged in.
- The
-
Postconditions:
- If there exists, the system returns a list of all available
bookings(those that have been selectedattend_offeringby the client). - If there are no
offeringsthat have been selectedattend_offering, an empty array is shown.
- If there exists, the system returns a list of all available
Interaction Diagram of Create Location (Admin):
Interaction Diagram of Create Offering (Admin):
Interaction Diagram of Delete Offering (Admin):
Interaction Diagram of Book (Client):
Interaction Diagram of Claim Offering (Instructor):
Interaction Diagram of Remove Attendee (Admin):
Interaction Diagram of Register (Guest User):
Interaction Diagram of Display Offerings (User):
Interaction Diagram of Display Unassigned Offerings (Admin, Instructor):
Interaction Diagram of Display Bookings (Client):
Interaction Diagram of Delete User (Admin):
“Offerings are unique. In other words, multiple offerings on the same day and time slot must be offered at a different location.”
context Offering
inv UniqueOfferingsByLocation:
Offering.allInstances()->forAll(o1, o2 |
o1 <> o2 implies
(o1.start_time <> o2.start_time or o1.end_time <> o2.end_time or o1.date <> o2.date or o1.location_id <> o2.location_id)
)
“Any client who is underage must necessarily be accompanied by an adult who acts as their guardian.”
context Booking
inv UnderageBooking:
self.client.age >= 18
“The city associated with an offering must be one the city’s that the instructor has indicated in their availabilities.”
context Offering
inv CityMatchesInstructorAvailability:
Instructor.allInstances()->exists(instructor |
instructor.id = self.instructor_id and
instructor.city = self.location.city)
“A client does not have multiple bookings on the same day and time slot.” (for simplicity we consider only identical day and time slots, even though in reality a booking on Monday 3pm – 4pm and another also on Monday 3:30pm – 4:30pm should not be acceptable.)
context Booking
inv NoMultipleBookingsForSameClientAndTime:
Booking.allInstances()->forAll(b1, b2 |
b1 <> b2 implies
(b1.client_id <> b2.client_id or b1.start_time <> b2.start_time or b1.end_time <> b2.end_time or b1.date <> b2.date)
)



