This project is for students who are taking courses from multiple years or curricula and are struggling to put together a good class schedule.
-
Start Docker Desktop.
-
Create a file called
secret-load.sql
at the top level of the project, with the following contents:INSERT INTO init_data (start_timestamp, end_timestamp, course_name, group_name) VALUES ('2022-06-26 08:00:00', '2022-06-26 10:00:00', 'Computer Systems', 'Y1G1'), ('2022-06-26 10:00:00', '2022-06-26 12:00:00', 'Web Development', 'Y1G1'), ('2022-06-26 14:00:00', '2022-06-26 16:00:00', 'Mobile Applications', 'Y1G1'), ('2022-06-26 10:00:00', '2022-06-26 12:00:00', 'Computer Systems', 'Y1G2'), ('2022-06-26 12:00:00', '2022-06-26 14:00:00', 'Web Development', 'Y1G2'), ('2022-06-26 14:00:00', '2022-06-26 16:00:00', 'Mobile Applications', 'Y1G2'), ('2022-06-26 08:00:00', '2022-06-26 10:00:00', 'Mobile Applications', 'Y1G3'), ('2022-06-26 12:00:00', '2022-06-26 14:00:00', 'Computer Systems', 'Y1G3'), ('2022-06-26 14:00:00', '2022-06-26 16:00:00', 'Web Development', 'Y1G3'), ('2022-06-26 08:00:00', '2022-06-26 10:00:00', 'Spaceship Technologies', 'Y2G1'), ('2022-06-26 10:00:00', '2022-06-26 12:00:00', 'Design', 'Y2G1');
This is the data that the database will be initialized with. It is also the only data that the application will have access to, so choose wisely! This simple dataset will do for now though.
-
Save
secret-load.sql
if you haven't already. -
Run the command
docker compose up
in your terminal. This will launch all the necessary Docker Containers and print their logs in the terminal.
Note: if you are getting
permission denied
in Linux, usesudo docker compose up
-
Wait until you see the line
Started ClassSchedulerBackendApplication in 1.792 seconds (process running for 1.932)
printed in the terminal. You should now be able to send GET requests to:
http://localhost:8080/api/class-schedule/courses
and receive a response similar to the following:
[ { "id": 1, "name": "Design" }, { "id": 51, "name": "Computer Systems" }, { "id": 101, "name": "Web Development" }, { "id": 151, "name": "Spaceship Technologies" }, { "id": 201, "name": "Mobile Applications" } ]
If you completed these steps, then your backend is running smoothly.
Get proposals for the given courses. Example usage: http://localhost:8080/api/class-schedule/proposals/1,51?count=2
courseIds
: a comma-separated list of course IDs in the formatcourseId1,courseId2,courseId3
. These are the course IDs of the courses that you want to take.
count
: the number of proposals that should be generated. Defaults to 10.
Returns count
number of proposals for the given courses.
[
{
"averageWeeklyOverlapCount": "0",
"combination": [
{
"id": 351,
"course": {
"id": 1,
"name": "Design"
},
"group": {
"id": 101,
"name": "Y2G1"
}
},
{
"id": 51,
"course": {
"id": 51,
"name": "Computer Systems"
},
"group": {
"id": 1,
"name": "Y1G1"
}
}
]
},
{
"averageWeeklyOverlapCount": "0",
"combination": [
{
"id": 351,
"course": {
"id": 1,
"name": "Design"
},
"group": {
"id": 101,
"name": "Y2G1"
}
},
{
"id": 451,
"course": {
"id": 51,
"name": "Computer Systems"
},
"group": {
"id": 151,
"name": "Y1G3"
}
}
]
}
]
- If duplicate course IDs are given.
- If empty course IDs are given.
- If negative
count
is given.
- If no course IDs are given.
- If invalid course IDs are given.
- If invalid
count
is given.
- If nonexistent course IDs are given.
Get all courses.
Returns all courses.
[
{
"id": 1,
"name": "Design"
},
{
"id": 51,
"name": "Computer Systems"
},
{
"id": 101,
"name": "Web Development"
},
{
"id": 151,
"name": "Spaceship Technologies"
},
{
"id": 201,
"name": "Mobile Applications"
}
]
Get all classes of the given course groups.
courseGroupIds
: a comma-separated list of course group IDs in the formatcourseGroupId1,courseGroupId2,courseGroupId3
.
Returns all classes of the given course groups.
[
{
"startTimestamp": "2022-06-26T10:00:00",
"endTimestamp": "2022-06-26T12:00:00",
"courseName": "Design",
"groupName": "Y2G1"
},
{
"startTimestamp": "2022-06-26T08:00:00",
"endTimestamp": "2022-06-26T10:00:00",
"courseName": "Computer Systems",
"groupName": "Y1G1"
}
]
- If duplicate course group IDs are given.
- If empty course group IDs are given.
- If no course group IDs are given.
- If invalid course group IDs are given.
- If nonexistent course group IDs are given.
The null
value is never used in our code. This is because Java is incapable of handling this edge case at compile time, thus resulting in NullPointerExceptions at runtime that are very hard to debug. As alternatives to null
, Optional and empty Collections are used. The only exceptions to this rule are null checks like if (o == null) ...
and tests. These tests will check our code's robustness against attacks from null
values.
Our domain is fully framework independent. In practice this means that our domain only consists of pure Java code. Any and all Spring Boot or Hibernate Persistence annotations, classes and interfaces only exist outside the domain. The only dependencies that the domain has, are framework independent libraries like Hibernate Validator.
ISO SQL is used whenever possible. This is to ensure easy portability to other SQL dialects with minimal changes. Any deviations from this rule are indicated by a comment.
Below are the database tables and relations represented in a relational model. These are the meanings:
- A trident means
many
. - An empty circle means
zero
. - A perpendicular line means
one
.
This project is licensed under the GNU General Public License version 2