Braden Hechmer, Daniel Mallett
The pomodoro technique is a time management exercise intended to help individuals focus more effectively and improve their work or study habits. It is a particularly useful tool during study sessions.
The goal of the pomodoro technique is to break up a long work or study session into more manageable pieces by working in brief intervals called "pomodoros," which are evenly spaced out by short breaks. The standard way to use this technique is to work for 25 minutes, then take a 5-minute break. For example, to study for about 2 hours including breaks, this would be split into 4 intervals for a total of 100 minutes of work, and a total of 20 minutes taken for breaks.
Rather than studying for 100 minutes straight, breaking the total time up into 25-minute chunks can make the work more manageable and allow an individual to work at a more sustainable pace. However, for some tasks, the standard 25-minute work period may not be enough time to effectively focus. In this case, there are a number of other common interval durations. But one problem is that it can be difficult to determine the optimal amount of time for a particular task and it can be frustrating and distracting to frequently adjust a timer when you feel like you need more or less time.
As users of the Pomodoro Technique ourselves, our team's motivation was to create a productivity tool with a pomodoro timer enhanced by machine learning, alongside a number of other productivity tools and features.
Our target customers are students and working professionals looking for effective time management techniques to work more efficiently. Our application provides target customers with a user-friendly pomodoro timer app. The timer is available to any individual accessing the site and creating an account provides access to some additional features. When a user creates an account, they can access a journal feature with an AI digital assistant, track their daily streak, and store their settings across sessions.
The journal allows users to reflect and record their thoughts about their work sessions. Our intention was to provide users with another feature to improve their work habits. These journal entries also serve as an additional source of data for machine learning.
A daily streak feature is a small way of encouraging users to continue using the application each day and become more consistent with their work habits. Other popular educational apps, such as Duolingo and LeetCode, also provide a similar streak feature to encourage consistent use.
One of our original goals was to develop an auto-adjusting feature for the timer, powered by machine learning, before the end of the semester. However, our team found it necessary to scale down and focus more on the core features of a standard Pomodoro timer. While we were unable to deliver on this goal within our original timeline, our team has future plans to continue developing this feature.
As a partial replacement for this missing functionality, we added some additional functionality to the journal. By integrating API calls to ChatGPT, a digital assistant appears in response to a user’s journal entries. The digital assistant is intended to provide valuable feedback and suggestions for the users, further differentiating our solution from existing pomodoro timers.
Our architecture heavily relies on the RedwoodJS Framework which provides popular technologies for the frontend, backend, and authentication. Our technology stack utilizes React, Javascript, TailwindCSS, Jest, Storybook, GraphQL, Prisma, PostgreSQL, Railway, OpenAI, and Auth0.
Our early implementations used a local SQLite database, which simplified testing. Later in the development process, we migrated our database to a Postgres database on Railway and integrated Auth0 as a third-party authentication provider for user accounts.
Figure 1: Final Architecture Diagram
Our first step was to design the look of our site in Figma. Then we started by building our dashboard and timer component. RedwoodJS made the process of creating these pages and components easy and intuitive. TailwindCSS was used to style the components and helped to streamline frontend development.
After creating this page and component and running some tests to ensure it all worked properly, we moved on to creating a navigation bar and started work on authentication. Building custom authentication proved to be tricky, so we instead chose to implement authentication with a third-party service, Auth0, an authentication provider that worked well but had its caveats. One of the issues we had with using Auth0 was that we had less control over the actual authentication page, so we weren’t able to integrate our own designs and forms. Using a third-party service for authentication also makes it more difficult to collect some data when users sign up for an account.
Figure 2: Preliminary Design in Figma
On the client-side, we have one main layout component, which contains a navigation bar and wraps around our main page which we call the Dashboard. The navigation bar holds the login/sign-out button, and the journal button. Initially, it held a button for the timer settings, but the settings made the most sense to be included inside our timer component since those are the only settings we provide at this time. The journal component and settings component are modal windows and are contained within the Dashboard page. They are conditionally rendered when users press their corresponding buttons. The state for these components as well as the timer is maintained by the layout with the React State Hook, and this state is made available to all relevant components with a Context Provider.
The RedwoodJS framework incorporates unit testing using Jest. For each layout, page, and component we created, we also had a separate test file with unit tests that runs when the test suite is run. Unit tests can also be run on individual components using the yarn rw test <component>
command. These tests were helpful for debugging and provided valuable information about our code's quality. The results of running our client and API test suites with Jest are shown below.
Note that a number of these tests are failing because the components they test are not being rendered anywhere in the application. These components include auto-generated forms for entering test data.
Figure 3: Results of Jest Client Test Suite
Figure 4: Results of Jest API Test Suite
On the back-end, alongside using the RedwoodJS framework for all of our database management and GraphQL calls, we also set up calls to OpenAI's chat assistant in order to provide feedback and responses to our user's journal entries. We interacted with the API through a service file that goes through GraphQL. The API call is made every time a user submits a new journal entry, and the AI agent is set up to respond to the user based on their past 5 journal entries.
Both development and planning roles shifted throughout the semester. Initially, Daniel Mallett planned to focus mostly on the client-side development, and Braden Hechmer planned to focus on the backend and development of our machine learning model. The planned development roles eventually changed, and members ended up contributing equally to all aspects of the project. Often, members focused more on implementing an entire feature, which required work on both the frontend and the backend. This workflow required equal collaboration on most code changes to ensure all team members were up to speed on changes that would affect their code. This cohesion was achieved by having both team members review each other’s pull requests and actively participate in code reviews. The project planning was done mainly by Daniel Mallett, who has some previous project management experience. However, planning also remained a collaborative process, with all members in agreement on the development timeline and the order in which features should be implemented. The team worked well together on this project, and all members are satisfied with the final result.
The project was broken down into four sprints, with each sprint lasting two weeks.
The focus of Sprint 1 was to plan out the work for the entire semester, design how we wanted the website to look, plan the architecture, and learn about the RedwoodJS framework. We created a Github Project that separates issues by milestone and used that as our main tool to plan our work. Then we created our initial design in Figma.
In Sprint 2, our main focus was the core pomodoro timer functionality. During this sprint, we created the home page, a navigation bar with settings, and a component for the timer itself. By the end of the second sprint, we were on schedule and had a functioning pomodoro timer with a few basic settings.
We implemented the ability for users to create accounts and authenticate using Auth0 as a third-party authentication provider. We also added functionality for the journal and some improvements to the user interface. At the end of this sprint, we had a completely functional pomodoro timer web application, which was our minimum goal. Looking back, if our team had more time to focus on the project or more members, much of this work could have been completed in the second sprint. Our biggest challenge was implementing some of the AI features, so it would have been beneficial to finish the base functionality early and allocate more time for the more unique features of our solution.
We decided to shift our focus away from the more complex features we had originally planned. We instead focused on deploying the site to get some initial user feedback and do some testing in our production and staging environments. In this sprint, we also implemented a digital assistant feature in the journal using an API call to ChatGPT. First, we cleaned up the UI, making it look more like our initial designs in Figma. Then, we cleaned up our feature branches and dev branches and merged all working changes into our main branch. Then, we set up a production database and a staging database using Railway. After some local testing with the new database, we moved forward to deploy with Netlify. Once the site was live, we started user acceptance testing and collecting preliminary feedback.
Our project was initially on schedule, but the team started to fall behind in the middle of the semester when the amount of coursework in other classes increased. Our biggest roadblock, aside from this, was a need for more familiarity with implementing a machine learning model for this task. In the end, we accomplished most of our original goals, but eventually, we had to pivot away from our initial goal to implement a machine learning model that automatically adjusts the timer.
The planning of the project went smoothly, and regular sprint planning meetings were beneficial. We could have improved planning further by also holding sprint reviews at the end of each sprint to get a better understanding of project status. On some occasions, issues that we had originally planned to complete were too much to handle in just one sprint, and perhaps we could have improved developer productivity by breaking these large issues into smaller ones.
The development process was fun and exciting. One thing we did well was having frequent code reviews, which led to improvements in code quality and maintainability. The team enjoyed working with the RedwoodJS framework and learned a lot about web development in the process.
While unit testing with Jest was integrated into our project from the beginning, it was often underutilized until later in the semester. One thing we could have done better was focusing more on test-driven development and writing better unit tests at the beginning.
Our team management was coordinated well, and we did a good job playing to our individual strengths. Only having two team members allowed us to work quickly and kept the complexity of our project to a minimum. However, we believe having a larger team might have enabled us to build a more comprehensive product. Often, all team members were occupied with outside commitments, and having a larger team to rely on would have alleviated much of the additional workload.
We consider the AI Pomodoro Timer a success because our final project meets almost all of our original goals. Users can sign up for an account, and our application provides a functioning Pomodoro timer with several additional features to improve productivity and work habits. Based on some preliminary feedback, users are satisfied with the design and functionality of our product.
We would have liked to implement an additional setting for automatically adjusting the timer with a machine learning algorithm, but unfortunately, we could not meet this goal within the original timeline. Looking back, we might have been able to achieve this had we focused more on this feature earlier on in the development process. Still, we were able to incorporate an AI digital assistant within the journal and have future plans to add more features. Users have also suggested adding more settings for customizing the appearance of the timer, with some additional options for background color and having the background color change between pomodoro intervals and breaks.