-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
Mode Relationship
The data structure diagram provided illustrates the interactions between different entities in the system designed to manage course schedules, wishlists, and calendars for users by accessing the University of Waterloo's OpenAPI. Here's an explanation of the key elements and their interactions:
-
User Interaction with UW OpenAPI: The core of this system is the interaction between the user and the University of Waterloo's OpenAPI. The user can request course schedules and information about courses offered through the API. This interaction is central to all other functionalities of the system.
-
Calendar and Course Management: Once the user retrieves course information from the OpenAPI, they can utilize this data in various ways:
- Calendar: The user can add courses to their calendar, creating a personalized schedule of the courses they are taking or interested in.
- Custom Calendar: For more tailored needs, the user can create a custom calendar. This involves first accessing the OpenAPI for course information, then processing this data according to the user's specific requirements, and finally adding it to a custom calendar.
- Wishlist: Users can also add courses to a Wishlist. This is achieved by first requesting course data from the OpenAPI and then storing the desired courses in the Wishlist for future reference or enrollment.
- Optimized Schedule: Users can send selected courses to this module, which then processes these courses to return an optimized schedule and thereby providing a more efficient and personalized academic schedule.
-
Social Features - Friends and Shared Calendars:
- Friend Requests and Shared Schedules: The system allows users to connect with friends. A user can send a friend request to another user. Once accepted, they can view each other's schedules. This feature enhances the collaborative aspect of the system, allowing students to coordinate or plan their schedules together.
- Visibility of Friend's Calendar: After a friend request is accepted, a user can access their friend's calendar data, providing an opportunity for shared planning.
-
Course-Related Data Entities: The diagram includes entities like 'User Course', 'User Custom Calendar', and 'Current Calendar Courses'. These represent different categories of course data processed and stored in the system. For instance, 'User Course' may represent the courses a user is currently enrolled in or interested in, while 'User Custom Calendar' could represent a user's uniquely created calendar based on specific criteria or preferences for future or current enrolment.
Overall, the data structure diagram outlines a comprehensive system for managing academic schedules and courses, integrating the University of Waterloo's OpenAPI for real-time course data, and enabling social interactions through shared calendars and friend functionalities. This system has been designed for ease of use, flexibility, and collaborative planning, tailored specifically for students at the University of Waterloo.
Entity Relationship
Our application needs to save multiple assets to a database in order for users to be able to view them again between sessions. We decided to use a relational database notably PostgreSQL notably due its wide use in the industry and its flexibility. As such, we have defined multiple tables in our database to store the assets we need. The following diagram provides the design of our database which includes all the entities and their relationships.
- Users: The Users table represents the users of our application. It contains an ID field which many entities will reference. It also stores the user’s username and password which has been hashed.
- UserCourses: The UserCourses table represents a user’s current selection of courses. This entity has a foreign key referencing a User through the user_id. As such, there is a one-to-many relationship between Users and UserCourses. A User can have many UserCourses, but all UserCourses reference one specific User. The UserCourse entity has its own ID and also stores information such as course_id, course_title, course_number, start_time, end_time, start_date, end_date, and week_pattern.
- CustomCalendars: The CustomCalendats table represents a user’s alternate schedules. Other than their current schedule, users can make alternate schedules with different courses. As such, this entity has a foreign key referencing a User through the user_id. There is a one-to-many relationship between Users and CustomCalendars. A user can have many CustomCalendars, but all CustomCalendars reference one specific User. The CustomCalendars has its own ID field and it also stores the name of the calendar.
- UserCalendarCourses: The UserCalendarCourses table represents the courses added to a CustomCalendar. Once a User makes a CustomCalendar, they can add courses to it. This entity has a foreign key referencing a CustomCalendar through the custom_calendar_id and a foreign key referencing a User through the user_id. As such, there is a one-to-many relationship between Users and UserCalendarCourses and a one-to-many relationship between CustomCalendars and UserCalendarCourses. The UserCalendarCourse entries are heavily linked to the CustomCalendars, so if a CustomCalendar is deleted, all of the associated UserCalendarCourses are also deleted in a cascade effect. The UserCalendarCourse entity has its own ID and also stores information such as course_id, course_title, course_number, start_time, end_time, and week_pattern.
- Friends: The Friends table represents the different requests for the friends system. Since to have a friends system, we have a many-to-many relationship between Users, we would need an association table which is what the Friends table is for. Thus, the Friends entity has two foreign keys each referencing a User through the user_id and the friend_id. It also has its own ID field and a status field which details the progress of a request. When a User sends a friend request to another user, an Friend entry is inserted and the status is set to “pending”. The other User then receives the request and can accept it or reject it. If rejected, the entry is deleted. If accepted, the status is changed to “accepted” and another entry is added for the opposite relationship. If a User is friends with another User, then the vice-versa is also true. Thus, two entries are needed to signify a friendship.
- Wishlists: The Wishlists table represents the courses a User wants in their wish list for one of the terms in their studies. The entity has a foreign key referencing a User through the user_id. As such, there is a one-to-many relationship between Users and Wishlists. A User can have many Wishlists, but each Wishlist is only associated with one User. The entity also has its own ID field and stores information such as subject_code, catalog_number, course_title, and term_year.
Layered Architecture
Our overall project has a layered architecture detailed by the following diagram. The first layer is the application layer which is our client. In the case of our project, it is a Desktop application. This layer has not changed since the proposal. The application layer will still depend on the common data models. One big change since the proposal is that our servers have been deployed to the cloud, more specifically on Google Cloud Platform using Cloud Run. Our Ktor and Spring Boot servers are both hosted on this service. As such, the application layer will talk to the cloud service. The cloud service will then route the request back to the respective server.
Now, initially, we planned on just having a Ktor server backend, but to implement our optimization feature, we needed to use an existing engine library to help us compute the answers for the scheduling problems. We found a very popular library called OptaPlanner, but it only supports backend frameworks such as Spring Boot and not Ktor. As such, we had to move our routes and logic for optimization to Spring Boot.
For our Ktor server backend, the layers stayed the same as the ones in the proposal. The first layer is the presentation layer which is where all of our API routes reside. The layer below is the business layer where all the business logic is applied. Compared to the initial proposal, some more logic for our different assets have been added including custom calendars logic and wishlist logic. The third layer is the service layer which acts as a middleware between the presentation layer and the persistence layer. The fourth layer is the persistence layer which talks to the database. While the layers in general stayed the same, they are not always respected. For example, some of the routes talk directly to the persistence layer. Moreover, for the business layer, there is not always a distinct layer for it. Some of the business logic can be applied in any of the other three layers. As such, for future projects, it might be worthwhile to define the layers better so that the code and the logic stay consistent. The Ktor layer still depends on the common data models. We have also opted for a cloud database notably PostgreSQL on Cloud SQL on GCP. As such, the persistence layer will directly talk to the cloud database.
For our Spring Boot server, it was not planned during the proposal. In our final project, the Spring Boot server is responsible for the optimization route. It is also hosted on Cloud Run. Requests to the optimization cloud routes will be directed to the Sprint Boot server. It has a presentation layer which contains the route. It also includes a business layer which is the layer where our planning engine will do the calculations following the constraints and return an answer.