A PRODUCT OF MY FRUSTRATION

Serao Academy: Beyond Enrollment

My jiu-jitsu gym's internal tool for membership and class enrollment is painfully slow, so I rewrote the backend to make action-response times >8x faster and unify manual tasks like verifying students and managing membership all under a single platform.
Despite the latency upgrade, many students still avoided visiting the platform, which I learned was due to poor UI, and because students didnt perceive any benefit from signing up for classes. In an effort to make the UI more intuitive and better align the product with students' motivations for coming to the gym, I redesigned the web platform to be more usable and valuable to the overall training experience.
Skills
Full-Stack
Web Development
UI Design
Database Design
Timeline
7 months
(Nov 2022 - May 2023)
Code / Frameworks
JavaScript, ReactJS, NextJS, Redux, HTML/CSS, GraphQL
Tools
AWS CDK (AppSync, Lambda, S3, DynamoDB, Cognito), Figma
A PRODUCT OF MY FRUSTRATION

Serao Academy: Beyond Enrollment

My jiu-jitsu gym's internal tool for membership and class enrollment is painfully slow, so I rewrote the backend to make action-response times >8x faster and unify manual tasks like verifying students and managing membership all under a single platform.
Additionally, the internal tool handles basic features like rankings, progress tracking, and profile management. However, those features were slow too, and their reductive design discourages students from using them at all. To fix this, I expanded those features to cultivate more engagement.
Once I got the back-end working with a provisional web UI, I prototyped a more visually satisfying experience for mobile devices.
Skills
Product Design
UX Research
Interaction Design
Timeline
2 months (Sep 2023 - Oct 2023)
Tools
Figma, Miro, Maze
Skills
Full-Stack
Web Development
UI Design
Database Design
Timeline
7 months
(Nov 2022 - May 2023)
Code / Frameworks
JavaScript, ReactJS, NextJS, Redux, HTML/CSS, GraphQL
Tools
AWS CDK (AppSync, Lambda, S3, DynamoDB, Cognito), Figma
BACKGROUND

Why the old thing sucked

I fell in love with jiu-jitsu back in high school, and I love going to the gym to learn new things and train with my buddies, kill-or-be-killed.
One thing I don't love though, is the web platform my gym has, which students use to sign up for classes, and Instructors use to monitor attendance and change the weekly schedule.

Signing up for classes is completely insufferable because server requests take upwards of 8 seconds to fulfill. Moreover, the page is re-rendered on each signup – which is especially troublesome on mobile devices where re-renders force you to scroll through through hundreds of attendees just to reach a single class at the bottom of the page.

See how long this takes? Visualize yourself signing up for 10 classes every week.
PRODUCT PLANNING & ARCHITECTURE

Developing for instructors & students

This problem extended not only to class signups, but also for nearly every action on the platform, like updating profile information or managing attendance. I outlined which areas of the platform needed improvement for both instructors and students:
Instructor
Leo
Manages students and classes
  • Responsible for approving new students
  • Verifies attendance for each class
  • Manages class schedule, breaks,, and holidays
  • Updates student ranks and contact information
Student
Me
Signs up and attends classes
  • Signs up for classes before attending
  • Prefers knowing class attendance in advance
  • Enjoys consistency and progress tracking
  • Likes to set goals and earn achievements
After assessing the needs of each group, I mapped out the necessary user flows and outlined how existing features could be improved. I considered not only backend improvements, but also potential changes in the front end. For example, I hypothesized that a GUI-style control center to manage users, classes, and attendees would simplify the management experience for instructors, and I wanted to ensure such a change could integrate well with the backend.

From there, it was a matter of determining which AWS services I needed to make those features work – which is a lot easier said than done, because I had a lot of trial and error to do the AWS CDK. After combing through a ton of docs, I was able to match the essential features/tasks with the right backend tools.
FULL-STACK DEVELOPMENT

Connecting the UI with back-end services

Once I finished planning the database layer, I architected the app's database using DynamoDB so I could help users store, get, and update information through AppSync. I deployed S3 buckets for object storage and used AWS Lambda to handle asynchronous invocations of long-latency & batch operations that happen in the background.
With the initial data infrastructure set up, I hosted the application using AWS Amplify and began coding the front-end web application. At this time, visual design was not the priority; what I needed was a navigable interface to conduct backend testing and ensure that CRUD functions could be executed from the front-end as intended.

Piecing together the front-end was straightforward using React and NextJS, which I opted for to take advantage of component-level CSS styling and server-side rendering (for heavier tasks like serving real-time updated class, attendance, and user details.) Most of my difficulties predictably came from the backend, which required a great deal of systematic learning and testing long after the initial UI was shipped.
A memorable struggle I faced with the back-end was figuring out how to handle signups for a moving range of available class dates. At any time, users can sign up for classes within a 7-day window starting on the current day. Each day of the week contains scheduled classes for that day, and every class has an upcoming date attributed in the database. Because there are an infinite number of future dates – the correct dates stored in each class (in each day) need to be updated on a daily basis.
For example, on Friday 11/30, all of Friday's classes have a date of 11/30. But starting Saturday 12/1, all of Friday's classes must have an updated date of 12/7. This is important because when users sign up for a class, that class must attribute the correct week and month to the user's overall training history.
To resolve this issue, I scheduled events using AWS Lambda, which automatically made updates to class dates at the end of the day. I used similar scheduled functions to automate other date-modification tasks like daily updates to each active user's training data, or disabling certain classes during scheduled holidays.
DESIGN PROCESS

Addressing additional problems through design

After extensive feature and bug testing on the simple front-end, this project was ready for deployment. I had completed my mission by cutting latency >90% (from 8 seconds to less than 1 second) and allowing the app to handle a more useful range of administrative tasks.

Despite the improved signup latency, many students STILL did not their change their signup habits. I conducted interviews with students who showed up for classes without signing up to find out why.
I had made the web platform faster, but the UI was still really poor - and students had to scroll really far down the page to sign up for a class at the end of the week.

Moreover, most students who didn't sign up for class felt that signing up for classes did not benefit them. To figure out how to solve these issues, I asked myself, how might I further simplify the class signup process? And, how might I make design improvements around signups in a way that meaningfully contributes to students' training?
Take progress tracking for example: the only data points students get are how many classes they've attended.
And the leaderboard too- it has never been reset and shows the same few students year-round, leaving no opportunity for other students to be recognized for training more often or consistently than the veterans.
Would improving these features help align the platform with students' motivations for training? What are students' motivations in the first place?
To answer these questions, I followed up with my interview participants to understand their motivations for coming to the gym, and brainstormed a few ideas I could implement through design.
I evaluated each of these ideas on the basis of Effort and Relative Value, where Effort is a function of the combined design effort, instructor, and engineering effort required to implement the solution; while Relative Value signifies how valuable the solution is, based on how aligned the solution is with students' motivations and how accessible or useful the next best alternative is.is a function of the combined design effort, instructor, and engineering effort required to implement the solution; while relative Value signifies how valuable the solution is, based on how aligned the solution is with students' motivations and how accessible or useful the next best alternative is.
I paid special attention to the engineering effort of each solution given my limitations as an engineer and the fact that I had undertaken a huge engineering effort already. Any major alterations to the platform's backend architecture or business logic would be beyond the scope of my design goals, since they would likely take way too much time for me build.

Therefore, ideal solutions would have to integrate easily with the platform's existing backend infrastructure - a consideration I didn't expect to have with my first design project.
With these ideas in mind, I planned to redesign the mobile UI to make it more intuitive (most students visit the platform via mobile). Then, I planned to improve the existing progress tracking chart, expand the existing leaderboard, allow students to set weekly training goals, and Implement unlockable achievements as ways to encourage users to visit the web platform. Focusing on the user flows surrounding these changes, I wireframed key interfaces & high-frequency interactions.
I received feedback on these wireframes by presenting them directly to students and asking them guided questions in relation to my objectives with each interface. After narrowing down my initial designs, I developed medium-fidelity mockups and tested them for usability, with a particular focus on how long users spend signing up for classes compared to the current signup UI, as well as the level of friction for new features like the expanded leaderboard and progress tracking.
For example, I experimented with how key pages are organized and how users are able to edit profile information, access class signups, view the global leaderboard, and manage their training progress.
I also tested various layouts for class signups. Based on the results, I chose a layout with quick date selection via carousel, and allowed users to sign up for classes with a single tap.
Final Design (Class Signup)
BEFORE
Problem: To sign up, users are forced to scroll past all attendees for all days leading up to a class
AFTER
Solution: One-tap signup, classes for the week organized via carousel, with a drop-down for attendee spoilers
BEFORE
Problem: To sign up, users are forced to scroll past all attendees for all days leading up to a class
AFTER
Problem: To sign up, users are forced to scroll past all attendees for all days leading up to a class
Solution: Classes categorized by day of the week with optional attendee spoilers and one-tap signup
Final Design (Training Progress)
BEFORE
Problem: Limited and information-dense progress tracking
AFTER
Solution: Visualized training history, with weekly goal setting & unlockable achievements to encourage activity
BEFORE
Problem: No visibility/editing for contact and enrollment information; very limited progress tracking
AFTER
Problem: No visibility/editing for contact and enrollment information; very limited progress tracking
Solution: Expanded range of editable personal information; user progress expanded to encourage activity
Final Design (Ranking & Top Performers)
BEFORE
Problem: Limited sense of competition and achievement since top ranks are not updated
AFTER
Solution: Categorized monthly and annual leaderboard expanded to all students
BEFORE
Problem: Limited sense of competition and achievement since top ranks are not updated
AFTER
Problem: Limited sense of competition and achievement since top ranks are not updated
Solution: Annually updating categorized leaderboard expanded to all students
Final Design (Management Tasks)
REFLECTIONS

Learnings and personal outcomes

A personal goal I had was to challenge myself and learn to use the AWS CDK, since I was only familiar with Firebase for handling back-end tasks like authentication, database management, and scheduled functions. By building this app, I experienced some of the capabilities, limitations, and challenges that come with implementing AWS services in a business project.

This was also my first crack at making a full-fledged product from scratch – something that can be used by hundreds of people – conceivably for an indefinite period of time. As a result, the application needed to be highly robust, so I took special care with bug testing and security checks (which I could sometimes half-ass in personal projects.)

Some learnings I had while building this app:
Designing within the context of engineering constraints
By the time I had started redesigning the mobile interface for this web app, I had already spent months engineering the site's backend infrastructure. Because my time and engineering expertise were both limited, I had to ensure my designs integrated neatly with the existing backend with minimal changes to the code.
Even though this is not a traditional handoff situation because I was both the designer and engineer, I gained experience in learning to design within the broader context of engineering and consider non-design constraints throughout the ideation and development process.
Be meticulous and disciplined with database design
Designing a back-end database from scratch was admittedly not easy for me. Often, I would "finish" and deploy my database layer to the project, only to realize that the database or schemas required further adjustments to enable a function I hadn't planned for in advance.
Once I set aside time to rigorously analyze and design the project's database, implementing and testing the backend turned into a far more bearable process.
Continuously challenge my own process
This project wouldn't have been possible if I didn't frequently question my process and seek outside resources to make things easier for myself. Often, my own annoyances had already been experienced and resolved by somebody else.
For example, my code became highly inefficient at one point due to heavy prop drilling across several functional components. When I got fed up with my own code, I discovered that I could use Redux to handle global states and merge state updates without passing data through many nested components – making my code much easier to work with. Seeking help like was invaluable for creating efficiencies in my own workflow.
EXIF Mapper: Digital Journeys
Ingrain: AI Interview Buddy