Skip to content

Conversation

@sophiestrausberg
Copy link
Contributor

Overview

Created average hourly capacity model to display popular times per hour for each gym, implemented JWT authentication with flask_jwt_extended, set up firebase cloud messaging and implemented notifications based on gym capacity and workout reminder times. Added migration for capacity reminders, workout reminders, and hourly average times.

Changes Made

Popular times
Created a new file (hourly_average_capacity.py) containing the HourlyAverageCapacity model, which stores the average capacity of a facility at a particular hour and day, averaging over the past 30 days. The HourlyAverageCapacity model stores facility_id, average_percent, hour_of_day, day_of_week, history (a float array containing previous capacity data for this hour from the past 30 days) and contains a function update_hourly_average(self, current_percent) to update the average_percent given new capacity data. Added scheduled task to update all hourly average capacity records each hour with the associated current capacity information. In capacities_scraper.py, added logic that is run with the scheduled task. In schema.py, added a mutation for retrieving average hourly capacities by facility_id.

Authentication
Use flask_jwt_extended to implement authentication with JWTs. In schema.py, added LoginUser mutation which creates a JWT token upon user login using create_access_token(), after login is successfully completed via Google on frontend. Defined a wrapper that verifies a JWT token from the Authentication header using verify_jwt_in_request(). Added wrapper to mutations and queries requiring authentication.

Messaging
In app.py, initialized the firebase app. Created capacity_reminder.py and workout_reminder.py to define the CapacityReminder and WorkoutReminder models respectively. CapacityReminder has columns for the associated gym, capacity_threshold, days_of_week, and is_active. WorkoutReminder stores days_of_week, reminder_time, and is_active. Both have a one-to-many relationship with User.

In schema.py, created mutations to create, delete, and toggle the is_active property of each reminder type. Creating a capacityReminder subscribes a user to a Firebase Messaging topic for {percent}{facility_name}{day_of_week} for each gym in gyms and each day in days_of_week. Unsubscribes user when the reminder's is_active column is False, or when the reminder is deleted.

Created messaging.py with the logic for sending capacity and workout reminders. Send_capacity_reminder sends a capacity reminder to the associated topic given a facility name and percent. Send_workout_reminders queries WorkoutReminder records and sends a payload to the device with the associated FCM token with message info and time. In app.py, added a scheduled task to call send_workout_reminders at 12 AM. In capacity_scraper.py, updated scraper to send workout reminders, comparing the previous capacity percent with the current percent per facility and sending reminders to topics between that range.

Test Coverage

Tested manually in graphQL and postman. Found no errors. Messages sent successfully.

@JoshD94
Copy link
Contributor

JoshD94 commented Jan 28, 2025

Seems like there is a failing test during build.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly does this file do? I think alembic has already been initialized, but maybe we were missing this file?

Copy link
Contributor

@JoshD94 JoshD94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs some changes, but LGTM

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to move scrape_classes out of the if statement? This will cause scrape_classes to run during migrations, which might cause an error because the migration is not complete before we run the scrape.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an explanation for changes to this file? I'm worried during deployment there will be a lot to debug due to the changes in migration code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of changes to the requirements, was there a reason behind this? Hopefully this works during deployment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fetch capacities function was recently changed and pushed to release because the URL changed. Will need to update this to match the currently deployed version. Should be simple, only two changed files are constants.py which had a new constant storing the new URL, and the fetch capacities function itself

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there was a build error pointing at this changed line. If its being referenced during build time, may need to ensure the variable is in the github workflow, because we build using github actions (containerizing).

Copy link
Contributor

@Aayush-Agnihotri Aayush-Agnihotri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, make sure to address Joshua's comments and fix any merge issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants