Portfolio
Introduction
// background
- I participate in many intramural sports teams during the season. That means I am on the IM Leagues application a lot putting together teams and checking what my schedule is for the week.
- IM Leagues is an application for managing teams, players, games, schedules, and everything else to intramural sports. To participate, a student must sign up and use the app.
// whats the problem?
- The problem with IM Leagues stems a lot from the fact that I am a software developer. The application is slow, un-responsive, littered with advertisements, the UI is poorly designed, confusing to navigate. It is irritating to use and it made me want to create my own version that fixed these problems.
- I was not able to find any alternatives or competitors. IM Leagues dominate most of the market share leaving no reason to improve or make changes.
// the solution
IM Leagues needs to be replaced
- Myself along with my roommate, who is a graphic designer, are passionate about intramural sports on campus. Together we have decided to design and create a replacement that will recreate the basic functionality needed for intramural sports while, improving on the drawbacks of IM Leauges.
Intramu is the solution
- It will be a new web application, designed and built from scratch with modern frameworks. It will solve these problems while making improvements for students to enjoy. In future versions a mobile application will also be created for users to fully enjoy Intrmamu
Requirements
% functional
- Secure login & registration for users & admins
- User dashboard for managing profile info, teams, and viewing network
- Team functionality like managing the roster and viewing schedules
- Invites & requests
- Admin dasboard for managing entire organization
- Make changes to players, teams, & admins
- Creating leagues, tournaments, and games
% non-functional
- Logging on back-end server
- Custom logging levels
- Logs to console and file
- Database backups
- Frequently backed up
- Periodic backups are maintaned
Technologies
` why these?
- When building a new application one must carefully consider the business cases when choosing the technology stack. Luckily, Intramu had the freedom to be built with any technology of choice. Because of this, the developer chose to use new and up-to-date technologies to keep the application modern.
` choices
- Intramu was built with React.js for the front-end with MobX managing its state. Vite manages the Javascript bundle and React Router controls the navigation around the application. It is all styled with Emotion css.
- The front-end communicates with a backed-end server running on Express.js & Node.js. It can handle thousands of simultaneous requests thanks to its event loop that will continue serving requests while, waiting on lengthy IO operations like a database. It logs requests and flow with Winston
- The back-end server uses a third party library pg, to query a PostgreSQL database modifying and adding new data. PostgreSQL is an enterprise level database that many big tech companies use. Plus it can handle large amount of data easily
- Security is performed by Auth0 on both the back & front-end for a secure experience
- Lastly, the portfolio and landing pages are built using Astro for speed
- Node.js v16.18 LTS
- React.js v18.2
- Vite v4.2.1
- Mobx 6.4
- React Router v6.4.2
- Emotion/React v11.10.6
- Express.js 5.0.0-beta.1
- Winston v3.8.2
- PostgreSQL v14.7
- Pg v8.8
- Auth0 v3.3 (Back-end)
- Auth0-React v2.0.1 (Front-end)
- Astro v2.3
- Visual Studio Code v1.72
` new technologies
- Learning TypeScript was new for me as I previously enjoyed the loose type checking. I had previous experience with React and Express, but never at a project this scale, so it required the maturing of my skills. Mobx and Emotion CSS were new and quick to pick up. Astro was completely new to me but it is pretty much just standard html and css with some features sprinkled in.
` best practices
N-Layer - Intramu was built using N-layer architecture to separate the various logical layers into tiers. Input validation is performed in the controller layer where it's then passed to the business layer to perform logic.
Comments - All code is commented with clear and concise comments to assist myself and other developers in understanding segments of code.
Prettier - Formatting and indentation can pose a huge problem when multiple developers are coding. Each may prefer a certain format. Prettier formats the entire codebase so it's consistent and easy to read.
Reusability - Intramu code is organized into reusable modules and components and the front and back-end of the application. The prevents code duplication and promotes reusability of code.
` cloud
- All of Intramu's services are currently deployed in the cloud. The portfolio and landing page are both hosted on GitHub Pages. The back-end server runs on a AWS ec2 instance communicating with a local database on the instance. The front-end is hosted on Vercel for simplicity. These all reside under the intramu.com domain.
- Unfortunately, due to time, full DevOp priniciples were not applied. There is a partial amount as all deployments, besides the back-end server will rebuild when a new push is made to GitHub keeping content up to date. However, there are clusters that will spin up new instances if any of these services go down. In the future, a separate server would run for the database and a pipeline would be set up to rebuild the back-end server when changes are made. The database, back-end server, and front-end would all be run on clusters to support varying loads and spin up new instances if a server went down.
Diagrams
Risks & Challenges
-- Risks
Not Using an ORM - ORM's can make retrieving data painless and easy to understand. I chose to write everything with raw SQL queries.
Switching to PostgreSQL - Early versions of the project utilized a MySQL database. This was switched to learn more of an enterprise database. This wasn't a huge risk but there are differences between MySQL and PostgreSQL that could cause issues.
-- Challenges
Database Design - This data is very hierarchical with many parent-child relationships
- When initially designing the database its very easy to draw the foreign keys from table to table. However, as I began to create the tables and query them I realized that this database will be much harder to design than initial thoughts. I looked at adjacency lists, nested sets, and bridge tables as alternatives, but these didn't work for my data. After meeting with my Professor we decided that a parent-child structure worked the best. Table joins have been relatively simple and as of now, there have been no glaring performance issues. This is of course with only a few rows per table. We will see how it performs when there are thousands of tables with multiple users querying.
Raw SQL queries - All queries are written with raw SQL, executing simple CRUD commands
- When starting the project I didn't think there would be that many CRUD methods, so I went with writing them all. As the project grew and I began to realize the complexity of the data, writing queries became more difficult and took longer to understand multiple table joins. Future versions of the application might possibly switch to an ORM like Prisma for future queries, and eventually migrate the entire codebase.
MobX State Management - MobX works like Redux to provide and control state around the application, making it easy to work with data
- When first learning React everyone handles state in the same simple way. However, as the application grows it becomes difficult to manage loading states, error states, global state, fetching and sending data. I found myself needing state in places where I simply could not get it without requesting it from the server again, or prop drilling it down to the component that needed it. This is where other solutions like Redux would come into play to help better manage this state. But, I didn't feel like the learning curve justified the difficulties I was facing with my application state. MobX was recommended by my mentor and at first I was unsure of switching. As I switched portions of the application I realized that MobX was simple to use and allowed me to have global state. I have since then switched all portions of the application to use MobX. However, this isn't without its drawbacks. The MobX documentation and community is small so simple errors can take longer to debug and fix. I randomly have issues and it can be challenging to fix them.
API design - API design is split into three logical sections
- The Player section are endpoints that require no roles and are accessible by everyone. The Organization section is only accessible to administrators. Lastly, the Maintenance section is a separate logic flow that doesn't enforce "Organization Separation". It is only accessible by Sudo users. The server didn't originally start like this, I eventually created these logical separations as I realized lumping them all together was confusing
Understanding Reusability - I had to learn to write more items into reusable functions and components
Issues
<!-- Front-end -->
Random State Issues with MobX - Random state issues where object variables are undefined. Prevents clean state organization and prevents some functions from firing.
Lack of Messages and Loading Icons - There are limited loading icons or error and success messages. It can make the application feel sluggish and unresponsive.
Poor Onboarding Experience - Logins and Signups go through a pre-made Auth0 page which can make the experience feel unfamiliar.
No Formal Design for Administration Portal - Proper designs still need to be drafted for the administration section
Unfinished Pages Around Application - Some unfinished pages around application where the template is created, but it still needs to be filled in with data and functionality
<!-- Back-end -->
Validation Not Fully Implemented On All Endpoints - Some endpoints don't have validation schemes and will accept data in any format
Documentation Lacks in Some Areas - API documentation lacks in some areas where new endpoints were created and modified without updating Swagger
No Tournament Functionality - Not in back-end or front-end