https://github.com/c-ehrlich/scheduler
Final project for Harvard University CS50. Web app that lets users create events and register for time slots.
https://github.com/c-ehrlich/scheduler
Last synced: about 1 year ago
JSON representation
Final project for Harvard University CS50. Web app that lets users create events and register for time slots.
- Host: GitHub
- URL: https://github.com/c-ehrlich/scheduler
- Owner: c-ehrlich
- Created: 2021-04-29T15:24:23.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2021-08-25T15:30:57.000Z (almost 5 years ago)
- Last Synced: 2024-10-05T14:43:15.232Z (over 1 year ago)
- Language: Python
- Size: 269 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Scheduler
#### Description: Final project for Harvard University CS50. Web app that lets users create events and register for time slots.
#### Video Demo: https://www.youtube.com/watch?v=cQ6SVQJTlwI


## Requirements
* cs50
* Flask
* Flask-Session
* requests
## Instructions (for demo usage)
1. Duplicate scheduler.backup and rename the copy to scheduler.db
2. In the root directory of the project, `flask run`
## Notable Features and Design Decisions
### UUIDs
Each event is identified by a UUID, using a system that I build as I wanted different tradeoffs than Python's built-in UUID functionality. UUIDs are used both internally to identify events, and user-facing for telling people about events, emailing links, etc. Internally the system is not case sensitive, but the user-facing UUIDs are always all-caps. Each UUID consists of exactly eight upper-case letters - much shorter than the ones generated by Python's internal UUID function. My reasoning for this was:
* Eight letters is a good length for a user-facing UUID as the length still allows for example transmitting for example by phone.
* Having only capital letters lets the system avoid common mistakes such as I/l, O/0, etc.
* 26^8 is about 200 billion - more than enough for UUIDs to be effectively impossible to guess or brute force.
### User Accounts
There is only one type of user account. This means that any user can both host and attend events.
### UI and other Front-End considerations
I tried to keep the UI as simple as possible, thinking back to the early web apps as I find many current trends in web design to be actively user hostile. Here are a few examples of considerations I made during the design process:
* High-contrast elements suggest the things the user will most commonly want to do
* For actions that we really don't want users to accidentally do, such as deleting events, buttons turn red on hover, and lead to a modal where the confirm button once again turns red on hover.
* Emphasis (for example the user's own name in a slot list) are achieved using simple html `` tags
* All front-end elements are designed so that user name fields support very long names - I checked all of them with the world's longest recorded human name.
* The front-end is almost entirely built in HTML and CSS, with maybe 20 lines of JS. A stretch goal for a future version of this project is to build it entirely without JS.
### Security & Data Integrity
* The app adheres to Flask's Best Practices for avoiding SQL injection
* Event hashes are guaranteed to be unique, and there are about 200 billion possible ones
* Event hashes are non-sequential, ie not guessable
* Backend security - the app is safe against injected JavaScript, bad requests, etc
* Users who are not the creator of an event cannot modify it
* Users cannot override other user's slots
* etc.
* Event slots must end after they start and cannot overlap
* No matter which order event slots are entered in, they appear correctly in all views
* All data and time information is validated for formatting before being input into the database
* And much more!
## Limitations & Wish List
### Deployment
* The app currently only runs in test mode in Flask. Likewise the DB, while fully functional, is probably not ready for real-world deployment.
### Accounts
* A mail server (for account confirmation, notifications about event changes, etc)
* Timezones (currently everything including the frontend runs in UTC)
* Support for multiple people per slot, for group events
* Safari on Mac prior to 14.1 (released April 2021) doesn't support "data" and "time" html input types properly, build a workaround for that
* "Garbage Bin" - Events go somewhere before being fully deleted, to allow restoring accidentally deleted events
* Transfer ownership of an event
* Improved mobile/responsive layout
## Database
* The database is normalized to 3NF.
### users
```
id INTEGER
username TEXT NOT NULL
hash TEXT NOT NULL
email TEXT NOT NULL
is_moderator INTEGER DEFAULT 0
PRIMARY KEY (id)
```
### events
```
id INTEGER
eventname TEXT NOT NULL
description TEXT NOT NULL DEFAULT ""
date STRING NOT NULL
owner_id INTEGER
hash TEXT NOT NULL
PRIMARY KEY (id)
FOREIGN KEY (owner_id) REFERENCES users (id)
```
#### slots
```
id INTEGER
time_start TEXT
time_end TEXT
event_id INTEGER NOT NULL
user_id INTEGER
PRIMARY KEY (id)
FOREIGN KEY (event_id) REFERENCES events (id)
FOREIGN KEY (user_id) REFERENCES users (id)
```
## Files and notes
### app.py
This contains most of the Model of the app.
### helpers.py
The contains several helper functions
* apology - This comes from CS50 Finance. Feed it an error code and it will display that error code alongside a cute cat
* delete_event - This deletes an event and all associated slots
* format_date - turnes a date such as "2021-05-21" into a more legible format such as "21. May 2021"
* join_event - makes a user join an event, and removes them from any other slots they are occupying in the current event
* leave_event - will remove a user from any slots they are attending in a given event
* get_end_time - gets the end time of an event
* get_start_time - gets the start time of an event
* verify_slots - assures that all slots of an event don't overlap and don't finish before they start
* week_day - returns the weekday (Monday, etc.) for a date with the date formating of the DB
* login_required - this comes from CS50 Finance. Checks that the user is logged in before executing a route
## Accounts and Events in sample DB
### Accounts (Name, Email, Password)
* David Malan david@cs50.io hunter2
* Doug Lloyd doug@cs50.io hunter2
* Brian Yu brian@cs50.io hunter2
* Christopher Ehrlich christopher@cs50.io hunter2
* Ernest and Berthold eandb@cs50.io hunter2
* Loretta Spears loretta@cs50.io hunter2
* Luc Tran luc@cs50.io hunter2
* Conrad Squires conrad@cs50.io hunter2
* Varun Dalby varun@cs50.io hunter2
* Ellesha Mackenzie ellesha@cs50.io hunter2
* Hettie Perez hettie@cs50.io hunter2
* Yousuf Parks yousuf@cs50.io hunter2
* Rikesh Jethanandani rikesh@cs50.io hunter2
* Xiaoshi Zhang xiaoshi@cs50.io hunter2
* Momoka Imamura momoka@cs50.io hunter2
### Events (Name, Date, Hash)
* CS50 Office Hours Week 3 - 26.4.2021 OISDRDTO
* CS50 Office Hours Week 4 - 03.5.2021 JAZNNFVC
* CS50 Office Hours Week 5 - 10.5.2021 SGWCDCZO
* CS50 Office Hours Week 6 - 17.5.2021 FGBLQRTV
* CS50 Office Hours Week 7 - 24.5.2021 OERGTPBI
* Design Tutorial - Silhouette Project - 07.5.2021 JVCNQOWG
* Midterm Presentation - Patternmaking 1 = 14.5.2021 GAYPYMBI
* Japanese N3 - Oral Presentation - 16.5.2021 SVPKOPTR